【问题标题】:Uncaught TypeError: Cannot read property '_listenId' of undefined - (Marionette, Backbone)未捕获的类型错误:无法读取未定义的属性“_listenId”-(木偶,骨干)
【发布时间】:2014-11-02 10:13:15
【问题描述】:

我一直在试验木偶的复合视图,但我的脚本不断出现错误“未捕获的类型错误:无法读取未定义的属性 '_listenId'”。彻底的 hack 表明复合视图永远不会触发“重置”事件:查看下面的代码: 我的模板

<script type="text/template" id="staff-list">
<thead>
  <tr>
    <th>First Name</th>
    <th>Last Name</th>
    <th>course</th>
  </tr>
</thead>
    <tbody>
    </tbody>
</script>

<script type="text/template" id="staff-list-item">
    <td><%= fname %></td>
    <td><%= lname %></td>
    <td><%= course %></td>
</script>

list_view.js

View.Staff = Backbone.Marionette.ItemView.extend({
    tagName: "tr",
    template: "#staff-list-item",
});
View.Staffs = Backbone.Marionette.CompositeView.extend({
    tagName: "table",
    className: "table table-hover",
    template: "#staff-list",
    emptyView: NoStaffsView,
    itemView: View.Staff,
    itemViewContainer: "tbody",

    initialize: function(){
        this.listenTo(this.collection, 'reset', function(){
            console.log("reset is called"); //it appears this is never reached
            this.appendHtml = function(collectionView, itemView){
            collectionView.$el.append(itemView.el);
            }
        });
    },

    onCompositeCollectionRendered: function(){
        this.appendHtml = function(collectionView, itemView){
            collectionView.$el.prepend(itemView.el);
        }
    }
});

list_controller.js

define(["app","apps/staff/list/list_view"], function(SchoolManager, View){
    SchoolManager.module("Staff.List", function(List, SchoolManager,Backbone, Marionette, $, _){
        List.Controller = {
            listStaffs: function(){
                require(["entities/staff"], function(){
                var fetchingStaffs = SchoolManager.request("staff:entities");
                var contactsListLayout = new View.Layout();
                var contactsListPanel = new View.Panel();
                $.when(fetchingStaffs).done(function(staffs){
                    var contactsListView = new View.Staffs({
                        collection: staffs
                    });

                    contactsListLayout.on("show", function(){
                        contactsListLayout.panelRegion.show(contactsListPanel);
                        contactsListLayout.staffsRegion.show(contactsListView);
                    });
                    //console.log("dasud");
                //console.log(staffs);
                SchoolManager.mainRegion.show(contactsListLayout);
            });
        });
        }
    }
    });
    return SchoolManager.Staff.List.Controller;
});

entitystaff.js

define(["app","../config/storage/localstorage"], function(SchoolManager){
    SchoolManager.module("Entities", function(Entities, SchoolManager, Backbone, Marionette, $, _){
    // Private
    // -------------------------
  Entities.Staff = Backbone.Model.extend({
    urlRoot: "staff",

    defaults: {
      fname: "",
      lname: "",
      course: ""
      },



    }); 
    // Public
    // -------------------------
  Entities.configureStorage(Entities.Staff);
  Entities.StaffCollection = Backbone.Collection.extend({
    url: "staff",
    model: Entities.Staff,
  });

   Entities.configureStorage(Entities.StaffCollection);
var initializeStaffs = function(){
    contacts = new Entities.StaffCollection([
      { id: 1, fname: "Alice", lname: "Arten", course: "555-0184" },
      { id: 2, fname: "Bob", lname: "Brigham", course: "555-0163" },
      { id: 3, fname: "Charlie", lname: "Campbell", course: "555-0129" }
    ]);
    contacts.forEach(function(contact){
      contact.save();
    });
    return contacts.models;
  };

 var API = {
    getStaffEntities: function(){
      var staffs = new Entities.StaffCollection();
      var defer = $.Deferred();
      staffs.fetch({
        success: function(data,response, options){
     //console.log("we are winners");
          defer.resolve(data,response, options);
        }
      });
      var promise = defer.promise();
      $.when(promise).done(function(staffs){
        if(staffs.length === 0){
          // if we don't have any contacts yet, create some for convenience
         // var models = initializeContacts();
         console.log("no initialization");
         var models = initializeStaffs();
          staffs.reset(models);
 //        var models = initializeContacts();
//          staffs.reset(models);
         // contacts.reset(models);
        }
      });
      return promise;
    },

    getStaffEntity: function(staffId){
      var staff = new Entities.Staff({id: staffId});
      var defer = $.Deferred();
      setTimeout(function(){
        staff.fetch({
          success: function(data){
            defer.resolve(data);
          },
          error: function(data){
            defer.resolve(undefined);
          }
        });
      }, 2000);
      return defer.promise();
    }
  };

  SchoolManager.reqres.setHandler("staff:entities", function(){
    return API.getStaffEntities();
  });

  SchoolManager.reqres.setHandler("staff:entity", function(id){
    return API.getStaffEntity(id);
  });

});

return;
});

我不知道我的代码有什么问题。我不断收到此错误: 未捕获的类型错误:无法读取未定义的属性“_listenId”

我做错了什么吗?还是版本有弃用?

【问题讨论】:

  • staffs 在这里是什么var contactsListView = new View.Staffs({ collection: staffs });
  • 来自 var fetchingStaffs = SchoolManager.request("staff:entities"); 来自 entitystaff.js SchoolManager.reqres.setHandler("staff:entities", function(){ return API.getStaffEntities(); });
  • 你使用的是哪个版本的木偶?
  • 我建议删除所有本地存储、API 内容并首先使用本地数据重新绘制一个简单的木偶视图,请参阅minimal reproducible example。如果可能,还可以考虑使用 4.x,更好的 API。

标签: javascript jquery backbone.js marionette


【解决方案1】:

在这里

            $.when(fetchingStaffs).done(function(staffs){
                var contactsListView = new View.Staffs({
                    collection: staffs
                });

staffs 需要是 Backbone.Collection 实例。然而,延迟查询的结果似乎只是一个简单的数组或对象。请参阅defer.resolve(data,response, options);,其中data 是ajax 请求的结果。

要修复getStaffEntities 函数,我会使用deferred.then() 进行链接,如下所示:

getStaffEntities : function () {
    var staffs = new Entities.StaffCollection();
    return staffs.fetch().then(function () {
        if (staffs.length === 0) {
            console.log("no initialization");
            var models = initializeStaffs();
            staffs.reset(models);
        }
        return $.when(staffs);
    });
}

【讨论】:

  • 感谢这个伟大的 sn-p 我很高兴。但是,如果您从我上面的代码中注意到,问题出在 list_view.js initialize:function(){ this.listenTo(this.collection, 'reset', function(){ console.log("reset is called"); //it appears this is never reached this.appendHtml = function(collectionView, itemView){ collectionView.$el.append(itemView.el); } }); } console.log('reset is called') 永远不会被调用,这意味着集合没有可用的重置
  • 这是因为在this.listenTo(this.collection, 'reset', function(){....this.collection 对象不是Backbone.Collection。
  • 仍然没有工作..所以我的来源有什么想法我做错了什么吗?或者我怎样才能让员工的收藏与我正在做的不同?
  • 请仍然期待任何帮助。
猜你喜欢
  • 2016-06-18
  • 2013-11-23
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
  • 2021-12-22
  • 2015-01-06
  • 2017-07-26
相关资源
最近更新 更多