2016-05-24 5 views
-2

Я пытаюсь использовать Backbone.js и довольно новичок в нем, но не могу привязываться к привязке this.listenTo правильно в функции инициализации View в следующем коде.Backbone.js TypeError: Не удается прочитать свойство undefined

Этот базовый код представляет собой отдельный файл js.

'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; 

Это называется в главном JS файл что-то вроде этого:

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

но бросает ошибку:

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

Проблема, как я проследить в журнале ошибок, кажется, здесь:

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

и

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

под ServiceView intialize функция;

this не определено при отправке. что мне не хватает?

Дайте мне знать, если есть какие-либо путаницы в отношении кода, я постараюсь сделать это проще.

+1

'$ el: $ ('# main')' причудливый, почему вы это делаете? Ваш вызов 'Function.prototype.bind' значения' initialize' также причудливый, что вы ожидаете от 'этого' в этом контексте и почему вы пытаетесь« привязать »там? –

+0

@muistooshort '$ el' - так что всякий раз, когда этот элемент выбран, это значение im выбирается. bind - Это означает, что я, должно быть, попробовал все, и в качестве последнего средства попытался связать с 'this', который является« App » – user2290820

+0

@muistooshort. Большинство примеров, которые я вижу, похожи на это http://backbonejs.org/docs/todos .html функция внутри jQuery. , но что делать, если я запускаю js-файл главной магистрали, импортированный в, скажем, главный файл. как бы вы предположили, что это должно быть выполнено? – user2290820

ответ

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

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

Оператор стрелки вызывается, когда определена функция инициализации. , только когда вызывается Preloadcart. Таким образом, при инициализации функции «это» не является viewobject, а «this», когда вызывается Preloadcart. использование обычная функция.

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

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

ах вы так правы. этот анонимный оператор был прост в написании, но большая боль в том, что вы знаете где. позвольте мне посмотреть, работает ли это. – user2290820

+1

Оператор стрелки должен использоваться в функции, а не в момент определения прототипа. –

+0

Вы знаете свой javascript – user2290820

Смежные вопросы