2016-05-24 22 views
-2

Ich probiere Backbone.js und ziemlich neu, aber kann nicht festhalten, diese this.listenTo richtig in der View Initialisierungsfunktion im folgenden Code zu binden.Backbone.js TypeError: Kann die Eigenschaft von undefined nicht lesen

Dieser Backbone-Code ist eine separate js-Datei.

$(() => { 
      Preloadcart($, Backbone, _, that); 
     }); 

aber führt den Fehler:

preloadCart.js:57 Uncaught TypeError: Cannot read property 'type' of undefined 

Das Problem, wie ich im Fehlerprotokoll scheint hier Spuren

'use strict'; 

let Preloadcart = function ($, Backbone, _) { 
    // console.log(Backbone); 
    console.log(this); 
    let 
    // fnSelf = this, 
    // Model-each unit comprises of this 
    Service = Backbone.Model.extend({ 
     defaults:{ 
     title:'', 
     price: 0, 
     checked: false 
     }, 

     type: 'Service', 

     toggleCheck:() => { 
     this.set('checked', !this.get('checked')); 
     } 
    }), 

    // Collection- of such Service instances 
    ServiceList = Backbone.Collection.extend({ 

     // collection based on this model 
     model: Service, 

     type: 'ServiceList', 

     // get model instances with attribute checked=true 
     getChecked:() => { 
     console.log(`checking ${this.type}`); 
     return this.where({checked:true}); 
     }, 
    }), 

    services = new ServiceList([ 
      new Service({ title: 'web development', price: 200}), 
      new Service({ title: 'web design', price: 250}), 
      new Service({ title: 'photography', price: 100}), 
      new Service({ title: 'coffee drinking', price: 10}) 
      // Add more here 
     ]), 

    // View of each Service model unit 
    ServiceView = Backbone.View.extend({ 
     tagName: 'li', 

     type: 'ServiceView', 

     events: { 
     'click': 'toggleService' 
     }, 

     initialize:() => { 
     console.log(`initializing ${this.type}`); 
     _.bindAll(this, 'toggleService', 'render'); 

     this.listenTo(this.model, 'change', this.render); 
     }, 

     toggleService:() => { 
     this.model.toggle(); 
     }, 

     render:() => { 
     let 
      $frag = $(document.createDocumentFragment()), 
      $htmlCheckbox = $('<input>', { 
      type:'checkbox', 
      value: 1, 
      name: this.model.get('title'), 
      }), 
      $htmlSpan = $('<span>', { 
      value: `\$${this.model.get('price')}`, 
      }); 

     $htmlCheckbox.append(this.model.get('title')); 
     $htmlCheckbox.append($htmlSpan); 
     this.$htmlCheckbox.prop('checked', this.model.get('checked')); 

     $frag.append($htmlCheckbox); 
     this.$el.append($frag); 

     return this; 
     } 
    }), 

    App = Backbone.View.extend({ 
     el: $('#main'), 

     type: 'App', 

     initialize: function() { 
     // listen on the collection instance of ServiceList, services 
     console.log(`initializing App ${this.type}`); 
     let 
      view, that= this; 
     this.total = 0, 
     this.collection = services; 

     _.bindAll(this, 'render'); 

     this.listenTo(this.collection, 'change', this.render); 

     _(this.collection.models).each((model) => { 
      view = new ServiceView(); 
      view.set({model: model}); 
      that.$('#services').append(view.render().el); 
     }, this); 
     }, 

     render:() => { 

     _.each(this.collection.getChecked(), (each) => { 
      this.total += each.get('price'); 
     }); 

     this.$('#total-value').text(`\$${this.total}`); 
     } 
    }), 

    AppView = new App(); 

    // new App(); 
    // return App; 

}; 


export default Preloadcart; 

Dies ist in der Haupt js Datei etwas wie folgt aufgerufen:

_.bindAll(this, 'toggleService', 'render'); 

und

console.log(`initializing ${this.type}`); 

unter ServiceView intialize Funktion;

this ist nicht definiert, wenn ich ausstelle. Was vermisse ich?

Lassen Sie mich wissen, wenn es etwas Verwirrung über den Code gibt, werde ich versuchen, dies einfacher zu machen.

+1

'$ el: $ ('# main')' ist bizarr, warum machst du das? Ihr 'Function.prototype.bind' Aufruf auf dem' initialize' Wert ist auch bizarr, was erwarten Sie von 'this' in diesem Kontext und warum versuchen Sie dort zu" binden "? –

+0

@muistooshort '$ el' - damit immer wenn dieses Element ausgewählt wird, der Wert ausgewählt wird. bind - Das bedeutet, ich muss alles versucht haben und als letzter Ausweg versucht, an die 'This' zu binden, die App ist – user2290820

+0

@muistooshort die meisten Beispiele, die ich sehe, sind wie folgt http://backbonejs.org/docs/todos .html die Funktion in einem jQuery. aber was ist, wenn ich eine Backbone-js-Datei importiert in, sagen wir eine Hauptdatei. Wie würden Sie vorschlagen, dass sollte ausgeführt werden? – user2290820

Antwort

1
initialize:() => { 
     console.log(`initializing ${this.type}`); 
     _.bindAll(this, 'toggleService', 'render'); 

     this.listenTo(this.model, 'change', this.render); 
     }, 

Der Pfeiloperator wird aufgerufen, wenn die Initialisierungsfunktion definiert ist. nur wenn der Preloadcart aufgerufen wird. In der Funktion initialize ist 'this' also nicht das viewobject, sondern 'this', wenn Preloadcart aufgerufen wird. Verwenden Sie die normale Funktion.

initialize: function() { 
      console.log(`initializing ${this.type}`); 
      _.bindAll(this, 'toggleService', 'render'); 

      this.listenTo(this.model, 'change', this.render); 
      }, 
+0

ah du bist so richtig. Dieser anonyme Operator war einfach zu schreiben, aber ein großer Schmerz-in-Sie wissen wo. Lass mich sehen, ob das funktioniert. – user2290820

+1

Arrow-Operator sollte in der Funktion verwendet werden, nicht die Zeit, wenn ein Prototyp definiert wird. –

+0

Sie wissen, Ihr Javascript – user2290820

Verwandte Themen