【问题标题】:Collection is not a function or Collection is not a constructor in BackboneCollection 不是 Backbone 中的函数或 Collection 不是构造函数
【发布时间】:2012-03-27 11:54:58
【问题描述】:

我的这段代码不断抛出错误,我不明白为什么。

var id = $(ev.currentTarget).data("id");
    var item = ItemCollection.getByCid(id);
    alert(item.get("ItemCode"));
    var qty = 1;
    var cartcollection = new CartCollection();
    cartcollection.add( item );
    CartListView.render();
    var itemcode = cartcollection.where({ItemCode: item.get("ItemCode")});
    if( itemcode.length > 0 ){ alert("success"); }

所以我想做的是检查 CartCollection 是否已经具有相同的模型,如果为真,它应该只更新模型的 Qty 属性。现在基于该代码,它返回 CartCollection 不是函数或构造函数。这到底是为什么!?有任何想法吗?谢谢

更新

我在这个上使用了主干、要求、KendoUI 网格和下划线,所以我的代码是这样的:

itemlist_view.js

define([
'jquery',
'underscore',
'backbone',
'model/item_model',
'model/cart_model',
'collection/item_collection',
'collection/cart_collection',
'view/cart/cartlist_view',
'text!templates/items/itemlist.html'
 ],function($, _, Backbone, Item, Cart, ItemCollection, CartCollection, CartListView, ItemListTemplate){

var ItemListView = Backbone.View.extend({
el: $("#mainContainer"),
events:{
    "click #itemListContainer li" : "AddToCart"
},
initialize: function(){
  this.model = Item;
  this.collection = ItemCollection;
  this.collection.bind("reset", this.render );
},
render: function(){
  var data = {
    items: ItemCollection.models
  }
  var compiledTemplate = _.template( ItemListTemplate , data);
  $("#itemContainer").html( compiledTemplate );
},
AddToCart:function(ev){
    ev.preventDefault();
    var id = $(ev.currentTarget).data("id");
    var item = ItemCollection.getByCid(id);
    alert(item.get("ItemCode"));
    var qty = 1;
    var cartcollection = new CartCollection();
    cartcollection.add( item );
    CartListView.render();
    var itemcode = cartcollection.where({ItemCode: item.get("ItemCode")});
    if( itemcode.length > 0 ){ alert("success"); }
}
});
return new ItemListView;
});

cart_collection.js

define([
'underscore',
'backbone',
'model/cart_model'
],function(_, Backbone, Cart){
var CartCollection = Backbone.Collection.extend({
    model: Cart,
  initialize: function(){

  }
});
return new CartCollection;
 });

cartlist_view.js

define([
 'jquery',
 'underscore',
 'backbone',
 'model/cart_model',
 'collection/cart_collection',
 'text!templates/cart/cartlist.html'
 ], function($, _, Backbone, Cart, CartCollection, CartListTemplate){

var Model = kendo.data.Model,
    ObservableArray = kendo.data.ObservableArray;

function wrapBackboneModel(backboneModel, fields) {
    return Model.define({
        fields: fields,
        init: function(model) {
            if (!(model instanceof backboneModel)) {
                model = new backboneModel(model);
            }

            Model.fn.init.call(this, model.toJSON());
            this.backbone = model;
        },
        set: function(field, value) {
            Model.fn.set.call(this, field, value);

            this.backbone.set(field, value);
        }
    });
}

function wrapBackboneCollection(model) {
    return ObservableArray.extend( {
        init: function(collection) {
            ObservableArray.fn.init.call(this, collection.models, model);

            this.collection = collection;
        },

        splice: function(index, howMany) {
            var itemsToInsert, removedItemx, idx, length;

            itemsToInsert = Array.prototype.slice.call(arguments, 2);

            removedItems = kendo.data.ObservableArray.fn.splice.apply(this, arguments);

            if (removedItems.length) {
                for (idx = 0, length = removedItems.length; idx < length; idx++) {
                    this.collection.remove(removedItems[idx].backbone);
                }
            }

            if (itemsToInsert.length) {
                for (idx = 0, length = itemsToInsert.length; idx < length; idx++) {
                    this.collection.unshift(itemsToInsert[idx].backbone);
                }
            }

            return removedItems;
        }
    });
}

kendobackboneCollection = wrapBackboneCollection;
kendobackboneModel = wrapBackboneModel;


var CartListView = Backbone.View.extend({
el: $("#cartContainer"),

initialize: function(){
  this.collection = CartCollection;
  this.model = Cart;
  this.collection.bind("change", this.render );
},
render: function(){
  console.log("here");
  this.el.html(CartListTemplate);
  var CartWrapper = kendobackboneModel(Cart, {
     ItemCode: { type: "string" },
     ItemDescription: { type: "string" },
     RetailPrice: { type: "string" },
     Qty: { type: "string" },
  });
  var CartCollectionWrapper = kendobackboneCollection(CartWrapper);

  this.$("#grid").kendoGrid({
    editable: true,
    toolbar: ["create"],
    columns: ["ItemDescription", "Qty", "RetailPrice"],
    dataSource: {
      schema: {model: CartWrapper},
      data: new CartCollectionWrapper(CartCollection),
     }
  });
  
},

});
return new CartListView;
});

【问题讨论】:

  • 那么你的错误到底是什么,它发生在哪里?
  • 你能把你创建CartCollection构造函数的代码贴出来吗?听起来原因将在该代码中。也许你没有在这个 sn-p 运行之前创建CartCollection
  • @tkone 错误是使用此代码 CartCollection.where();它说 CartCollection 不是一个函数。如果我将实例化它 cartcollection = new CartCollection();然后使用 cartcollection.where() 它说 CartCollection 不是构造函数。
  • @silent__thought 我更新了上面的代码。就像你问的那样,我包含了视图和集合。

标签: javascript backbone.js requirejs kendo-ui


【解决方案1】:

我认为问题在于您正在双重实例化CartCollection。也就是说,cart_collection.js 返回一个 new CartCollection() 并在 itemlist_view.js 中再次使用 var cartcollection = new CartCollection(); 实例化它。

将该行更改为var cartcollection = CartCollection;,看看效果如何。显然,您也可以删除 cartcollection 变量并将其用法替换为 CartCollection

另一方面,我会认真考虑不从您的cart_collection.js 返回new CartCollection()。这感觉像是一种非常糟糕的做法,因为您将只能使用该集合的一个实例。此外,对于开发人员来说,他们返回集合的实例而不是它的构造函数并不明显。

我建议返回CartCollection instaed,然后使用new CartCollection() 在您的itemlist_view.js 文件中实例化它。这样,您以后可以在需要时实例化更多这些集合。

同样建议 cartlist_view.js 返回 new CartListView()

【讨论】:

  • 我将您的答案标记为正确,因为我对模型也有疑问,而您对我的模型问题的回答是正确的。但是对于集合,因为我在我的 cart_collection.js 上返回了新的 CartCollection,我应该直接在我的视图上使用 CartCollection。但是 CartCollection.where({itemcode : item.get("itemcode")}) 问题仍然存在。它仍然说 CartCollection.where 不是函数。这会是一个错误吗?因为我可以添加,但是 where 函数不起作用。
  • 啊。集合没有where 函数让我很震惊。您可能想要 filter 函数。
  • 就是这样。但是根据文档,它具有 where 功能。谢啦。 ;)
  • 只是想根据您的建议询问不要在模型和系列上返回“新”。我做到了,但问题是我可以在 itemlist_view 上向 cartcollection 添加一个项目,但是当我调用渲染(在 firebug 中使用断点)时,添加的数据不会出现在 cartlist_view 文件中。
猜你喜欢
  • 2015-10-15
  • 2018-09-17
  • 2019-05-28
  • 2022-06-14
  • 2014-02-25
  • 1970-01-01
  • 2019-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多