1

Ich habe Probleme mit Objektbereich.Zugriff Objektkontext von Prototyp-Funktionen JavaScript

Hier ist mein Klassencode

// 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"])); 
       } 
      }; 
     })(); 

Ich habe Probleme mit Objektfeldern zugreifen.

Ich habe versucht, self zu verwenden, um den aufrufenden Bereich zu erhalten. Aber weil es zuerst vom globalen Geltungsbereich initialisiert wird, erhalte ich Window Objekt in _self gespeichert.

Ohne _self nur mit this funktioniert es auch nicht. Da kann ich raten, dass meine Funktionen fetchItemsList aus dem jTable Kontext aufgerufen werden und dann auf Window Objekt zeigt, so bekomme ich Fehler undefined.

Ich habe verschiedene Möglichkeiten ausprobiert, aber keiner von ihnen funktioniert.

Bitte schlagen Sie vor, wie ich dieses Problem lösen kann.

Thx.

UPDATE

ist hier Version mit allen Verfahren als öffentlich ausgesetzt.

  // 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

Der springende Punkt des Prototyps ist, dass die Methoden gemeinsam genutzt werden müssen, um 'this' im Körper der Methode zu verwenden ?! Sie können diese '_self'-Methode nur innerhalb des Konstruktors verwenden, in dem Sie bereits eine Instanz haben. – Bergi

+0

Ja du hast recht, das geht nicht, das ist nur ein Beispiel wie ich versucht habe zu lösen und ich erklärte warum das nicht funktioniert, ich suche nach einer anderen Lösung. Also habe ich diese Frage gestellt. – CROSP

+0

Mögliches Duplikat von [JavaScript private methods] (http://stackoverflow.com/questions/55611/javascript-private-methods) –

Antwort

0

Ihre Zuordnung einer Funktion direkt zum Prototyp. DynamicItemList.prototype= Normalerweise ist es das Formular DynamicItemList.prototype.somefunc=

+0

Ja, aber wie Sie sehen können, wird diese Funktion selbst ausgeführt und gibt das Objekt selbst zurück, das einige andere Funktionen enthält. Ich habe dies wegen privater Methoden getan. Ist es möglich, Methoden geheim zu halten und nur bestimmte Teile freizulegen, so wie ich es getan habe? – CROSP

2

Danke allen für Hilfe, ich habe gerade herausgefunden, wo das Problem ist.

Wie für die letzte Version mit Methoden als öffentlich angezeigt. Problematische Teil ist

$(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 
       }); 
      }; 

Hier neues Objekt erstellt, die keine Ahnung von Variable-Objekt hat, wo sie erzeugt wird.

Ich habe meinen Code folgendermaßen geändert, wie Sie oben sehen können.

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

Und jetzt funktioniert es wie ein Charme. Wenn diese Methode Nachteile hat, lass es mich wissen. Mein Problem war anfänglich in diesem Teil, und Methoden privat zu halten macht keinen Sinn, weil mein Objekt von einer anderen Bibliothek benutzt wird.

Thx jeder.

0

Sie benötigen Prototyp Methoden verwenden, um die this Schlüsselwort zu machen (so dass sie dyynamically die Instanz erhalten sie aufgefordert wurden), aber Sie müssen bind the instance in the callbacks, die Sie in jtable passieren.

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 
    }); 
}; 
Verwandte Themen