1

개체 범위에 문제가 있습니다.프로토 타입 함수에서 개체 컨텍스트에 액세스 JavaScript

여기 내 클래스 코드

// Table list module 
     function DynamicItemList(data, settings, fields) { 
      if (!(this instanceof DynamicItemList)) { 
       return new DynamicItemList(data, settings, fields); 
      } 
      this.data = data; 
      this.settings = settings; 
      this.fields = fields; 
      this.dataSet = { 
       "Result": "OK", 
       "Records": this.data ? JSON.parse(this.data) : [] 
      }; 
      this.items = this.dataSet["Records"]; 
      this.generateId = makeIdCounter(findMaxInArray(this.dataSet["Records"], "id") + 1); 
      this.dataHiddenInput = $(this.settings["hidden-input"]); 
     } 

     DynamicItemList.RESULT_OK = {"Result": "OK"}; 
     DynamicItemList.RESULT_ERROR = {"Result": "Error", "Message": "Error occurred"}; 
     DynamicItemList.prototype = (function() { 
      var _self = this; 
      var fetchItemsList = function (postData, jtParams) { 
       return _self.dataSet; 
      }; 
      var createItem = function (item) { 
       item = parseQueryString(item); 
       item.id = this.generateId(); 
       _self.items.push(item); 
       return { 
        "Result": "OK", 
        "Record": item 
       } 
      }; 
      var removeItem = function (postData) { 
       _self.items = removeFromArrayByPropertyValue(_self.items, "id", postData.id); 
       _self.dataSet["Records"] = _self.items; 
       _self.generateId = makeIdCounter(findMaxInArray(_self.dataSet["Records"], "id") + 1); 
       return DynamicItemList.RESULT_OK; 
      }; 
      return { 
       setupTable: function() { 
        $(_self.settings["table-container"]).jtable({ 
         title: _self.settings['title'], 
         actions: { 
          listAction: fetchItemsList, 
          deleteAction: removeItem 
         }, 
         fields: _self.fields 
        }); 
       }, 
       load: function() { 
        $(_self.settings['table-container']).jtable('load'); 
       }, 
       submit: function() { 
        _self.dataHiddenInput.val(JSON.stringify(_self.dataSet["Records"])); 
       } 
      }; 
     })(); 

내가 개체 필드를 액세스에 문제가있는 것입니다.

전화 범위를 유지하기 위해 self을 사용하려고했습니다. 하지만 먼저 전역 범위에서 초기화되므로 에 저장되는 Window 개체가 생성됩니다.

_self이 없으면 this뿐입니다. 작동하지 않습니다. 때문에 내 함수를 fetchItemsListjTable 컨텍스트에서 호출되고이보다 Window 개체를 가리키는 것 같아서, 그래서 내가 undefined 오류가 발생합니다.

나는 여러 가지 방법을 시도했지만 그 중 아무 것도 작동하지 않습니다.

이 문제를 어떻게 해결할 수 있는지 제안 해주십시오.

Thx. 여기

UPDATE

모든 방법 버전 공개로 노출되고있다.

  // Table list module 
     function DynamicItemList(data, settings, fields) { 
      if (!(this instanceof DynamicItemList)) { 
       return new DynamicItemList(data, settings, fields); 
      } 
      this.data = data; 
      this.settings = settings; 
      this.fields = fields; 
      this.dataSet = { 
       "Result": "OK", 
       "Records": this.data ? JSON.parse(this.data) : [] 
      }; 
      this.items = this.dataSet["Records"]; 
      this.generateId = makeIdCounter(findMaxInArray(this.dataSet["Records"], "id") + 1); 
      this.dataHiddenInput = $(this.settings["hidden-input"]); 
     } 

     DynamicItemList.RESULT_OK = {"Result": "OK"}; 
     DynamicItemList.RESULT_ERROR = {"Result": "Error", "Message": "Error occurred"}; 
     DynamicItemList.prototype.fetchItemsList = function (postData, jtParams) { 
      return this.dataSet; 
     }; 
     DynamicItemList.prototype.createItem = function (item) { 
      item = parseQueryString(item); 
      item.id = this.generateId(); 
      this.items.push(item); 
      return { 
       "Result": "OK", 
       "Record": item 
      } 
     }; 
     DynamicItemList.prototype.setupTable = function() { 
      $(this.settings["table-container"]).jtable({ 
       title: this.settings['title'], 
       actions: this, 
       fields: this.fields 
      }); 
     }; 
     DynamicItemList.prototype.load = function() { 
      $(this.settings['table-container']).jtable('load'); 
     }; 
     DynamicItemList.prototype.submit = function() { 
      this.dataHiddenInput.val(JSON.stringify(this.dataSet["Records"])); 
     }; 
     DynamicItemList.prototype.removeItem = function (postData) { 
      this.items = removeFromArrayByPropertyValue(this.items, "id", postData.id); 
      this.dataSet["Records"] = this.items; 
      this.generateId = makeIdCounter(findMaxInArray(this.dataSet["Records"], "id") + 1); 
      return DynamicItemList.RESULT_OK; 
     }; 
     DynamicItemList.prototype.updateItem = function (postData) { 
      postData = parseQueryString(postData); 
      var indexObjToUpdate = findIndexOfObjByPropertyValue(this.items, "id", postData.id); 
      if (indexObjToUpdate >= 0) { 
       this.items[indexObjToUpdate] = postData; 
       return DynamicItemList.RESULT_OK; 
      } 
      else { 
       return DynamicItemList.RESULT_ERROR; 
      } 

     }; 
+0

프로토 타입의 요점은 메소드가 메소드 본문에서'this'를 사용해야한다는 것입니다. 인스턴스를 이미 가지고있는 생성자 안에서만'_self' 접근법을 사용할 수 있습니다. – Bergi

+0

네가 맞다. 이것이 작동하지 않는다. 이것은 단지 내가 풀려고했던 방법 일 뿐이며, 왜 이것이 작동하지 않는지 설명했다. 나는 다른 해결책을 찾고있다. 그래서 나는이 질문을했다. – CROSP

+0

가능한 경우 [JavaScript private methods] (http://stackoverflow.com/questions/55611/javascript-private-methods) –

답변

0

기능을 프로토 타입에 직접 지정합니다. DynamicItemList.prototype= 일반적으로 양식입니다. DynamicItemList.prototype.somefunc=

+0

예, 볼 수 있듯이이 함수는 자체적으로 실행되며 다른 함수가 포함 된 객체 자체를 반환합니다. 나는 개인적인 방법 때문에 이것을했다. 메서드를 비공개로 유지하고 특정 파트 만 노출 할 수 있습니까? 예를 들어 작동 시키십시오.) – CROSP

2

모두에게 감사드립니다. 문제가있는 부분을 알아 냈습니다.

공개로 공개 된 메소드가있는 마지막 버전입니다. 문제있는 부분

$(this.settings["table-container"]).jtable({ 
        title: this.settings['title'], 
        actions: { 
         listAction: this.fetchItemsList, 
         createAction: this.createItem, 
         updateAction: this.updateItem, 
         deleteAction: this.removeItem 
        }, 
        fields: this.fields 
       }); 
      }; 

여기서 새로운 객체가 생성되는 객체의 변수에 대해 모르고있다하는 생성된다.

위에서 본 것처럼 코드를 다음과 같이 변경했습니다.

$(this.settings["table-container"]).jtable({ 
       title: this.settings['title'], 
       actions: this, 
       fields: this.fields 
      }); 

이제는 매력처럼 작동합니다. 이 방법에 단점이있는 경우 알려 주시기 바랍니다. 내 문제는 처음에는이 부분에 있었고 메서드를 비공개로 유지하는 것은 내 개체가 다른 라이브러리에서 사용되기 때문에 의미가 없습니다.

Thx 모두.

0

프로토 타입 메서드가 this 키워드를 사용하여 (동적으로 해당 인스턴스가 수신되도록) 사용해야하지만 으로 전달하는 bind the instance in the callbacks이 필요합니다.

DynamicItemList.prototype.setupTable = function() { 
    var self = this; 
    function fetchItemsList(postData, jtParams) { 
     return self.dataSet; 
    } 
    function createItem(item) { 
     item = parseQueryString(item); 
     item.id = self.generateId(); 
     self.items.push(item); 
     return { 
      "Result": "OK", 
      "Record": item 
     }; 
    } 
    … // other callbacks 

    $(this.settings["table-container"]).jtable({ 
     title: this.settings['title'], 
     actions: { 
      listAction: fetchItemsList, 
      createAction: createItem, 
      updateAction: updateItem, 
      deleteAction: removeItem 
     }, 
     fields: this.fields 
    }); 
}; 
관련 문제