Backbone.js TypeError: Cannot read property of undefined

Backbone.js TypeError: Cannot read property of undefined

我正在尝试 Backbone.js 并且对它很陌生,但无法在以下代码的视图初始化函数中正确确定绑定 this.listenTo。

这个backbone代码是一个单独的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 在我输出的时候是未定义的。我错过了什么?

如果对代码有任何混淆,请告诉我,我会尽量简化。

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

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

箭头运算符在定义初始化函数时被调用。 就在调用 Preloadcart 时。所以在initialize函数中,'this'不是viewobject,而是调用Preloadcart时的'this'。使用正常功能。

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

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