Backbone.js Backbone Collection.fetch为我提供了未捕获的TypeError:对象不是函数
我正在开发一个带有Backbone.js Backbone Collection.fetch为我提供了未捕获的TypeError:对象不是函数,backbone.js,collections,Backbone.js,Collections,我正在开发一个带有RequireJS和lodash库的Backbone应用程序,一切正常,但我在将json数据设置到我的集合对象时遇到了问题 RequireJS配置: require.config({ baseUrl: 'js', paths: { // Aliases for libraries, so that we can change versions from here jquery: 'libs/jquery-1.10.min', // Lo-Dash is
RequireJS
和lodash
库的Backbone
应用程序,一切正常,但我在将json
数据设置到我的集合
对象时遇到了问题
RequireJS
配置:
require.config({
baseUrl: 'js',
paths: {
// Aliases for libraries, so that we can change versions from here
jquery: 'libs/jquery-1.10.min',
// Lo-Dash is a better drop-in replacement for Underscore: http://lodash.com/
lodash: 'libs/lodash-1.2.0.min',
requireLib: 'libs/require-2.1.6-min',
almondLib: 'libs/almond-0.2.5',
backbone: 'libs/backbone-1.0.0.min',
less:'libs/less-1.4.0.min'
},
shim: {
'backbone': {
//These script dependencies should be loaded before loading
//backbone.js
deps: ['lodash', 'jquery'],
//Once loaded, use the global 'Backbone' as the
//module value.
exports: 'Backbone'
}
},
// This is appended to every module loading request, for cache invalidation purposes
urlArgs: "bust=" + (new Date()).getTime()
});
和我的page.html
<script type="text/javascript">
require(["app/views/catalog"], function (Catalog) {
var app = new Catalog.App();
});
//require(['libraries', 'cs!auth-main']);
</script>
这是我的收藏
库
define([
'jquery',
'lodash',
'backbone'
],
function ($, _, Backbone) {
var CatalogModel = {};
CatalogModel.App = Backbone.Model.extend({
defaults: {
name: "Catalog without name",
userdata: false,
documents: false
},
initialize:function () {
console.log("Model - App.initialize");
this.on("change", function () {
console.log("Model - App.change");
});
},
url:"json/logged_data.json"
});
CatalogModel.User = Backbone.Model.extend({
defaults: {
username: "Default username"
},
initialize: function () {
console.log("Model - User.initialize");
this.on("change", function () {
console.log("Model - User.change");
});
}
});
CatalogModel.Document = Backbone.Model.extend({
defaults: {
name: "Default catalog name",
status: {
url: "#",
ready: false,
downloadableProductUrl: "#"
}
},
initialize: function () {
//console.log("CatalogModel.DocumentBrowse.initialize");
this.on("change", function () {
console.log("Model - Document.change");
});
}
});
CatalogModel.Asset = Backbone.Model.extend({
defaults: {
nodeType:"folder",
name:"Default folder name",
url:false,
treeId:"0",
collection:false
},
initialize: function () {
console.log("Model - Asset.initialize");
this.on("change", function () {
console.log("Model - Asset.change");
});
}
});
return CatalogModel;
}
);
define([
'jquery',
'lodash',
'backbone',
'app/models/catalog'
],
function ($, _, Backbone, CatalogModel) {
var CatalogCollection = {};
CatalogCollection.DocumentsList = Backbone.Collection.extend({
initialize: function () {
console.log("Collection - DocumentsList.initialize");
this.model = new CatalogModel.Document();
this.on("add", function () {
console.log("Collection - DocumentsList.add");
});
}
});
CatalogCollection.AssetsList = Backbone.Collection.extend({
initialize: function () {
console.log("Collection - AssetsList.initialize");
this.model = new CatalogModel.Asset();
this.on("add", function () {
console.log("Collection - AssetsList.change");
});
},
parse: function(response) {
console.log("Collection - AssetsList.parse");
//console.log(response);
return response;
},
url:"json/assets_nodes.json"
});
return CatalogCollection;
}
);
define([
'jquery',
'lodash',
'backbone',
'app/models/catalog',
'app/collections/catalog',
'libs/text!app/templates/account_bar.html',
'libs/text!app/templates/document_browser.html',
'libs/text!app/templates/document_editor.html',
'libs/text!app/templates/document_name.html',
'libs/text!app/templates/assets_nodes.html',
'libs/text!app/templates/assets_children.html'
// ,'libs/text!app/templates/assets_items.html'
],
function ($, _, Backbone, CatalogModel, CatalogCollection, tmplAccountBar, tmplDocumentsBrowser, tmplDocumentEditor, tmplDocumentName, tmplAssetsNodes, tmplAssetsChildren) {
var Catalog = {};
Catalog.App = Backbone.View.extend({
el: $("#catalog"),
initialize: function() {
console.log("View - App.inizialize");
this.tmplDocumentEditor = tmplDocumentEditor;
// here i'll set subviews for user bar, doc browser, assets list and book editor
this.UserBarSubView = new Catalog.UserBarView();
this.DocumentsBrowserSubView = new Catalog.DocumentsBrowserView();
this.AssetsBrowserSubView = new Catalog.AssetsBrowserView();
this.UserBarSubView.parent = this;
this.DocumentsBrowserSubView.parent = this;
this.AssetsBrowserSubView.parent = this;
this.model = new CatalogModel.App();
this.listenTo(this.model, "change", this.updateMainRequest);
this.model.fetch(null);
},
updateMainRequest: function(data){
var data = this.model.toJSON();
console.log("View - App.updateMainRequest");
//console.log(data.documents);
this.UserBarSubView.model.set(data.userdata);
var documents = [];
for (var i = data.documents.length - 1; i >= 0; i--) {
documents.push(new CatalogModel.Document(data.documents[i]));
};
this.DocumentsBrowserSubView.collection.set(documents);
},
createDocument: function() {
console.log("View - App.createDocument");
var name = this.model.get("name");
//console.log(name);
this.renderDocumentEditor(name);
},
editDocument: function(index) {
console.log("View - App.editDocument");
console.log(index);
},
renderDocumentEditor: function(name) {
console.log("View - App.renderDocumentEditor");
this.$el.find("#docs-browser").remove();
this.$el.append(this.tmplDocumentEditor);
this.AssetsBrowserSubView.renderDocumentName({name:name});
this.AssetsBrowserSubView.collection.fetch();
/*
this.$el.find("#assets").html("assets creato dinamicamente");
this.$el.find("#document-opened").html("doc opened creato dinamicamente");
*/
}
});
Catalog.UserBarView = Backbone.View.extend({
initialize: function() {
console.log("View - UserBar.inizialize");
this.template = tmplAccountBar;
this.model = new CatalogModel.User();
// data updates will be managed from Catalog.App
this.listenTo(this.model, "change", this.render);
},
render: function() {
console.log("View - UserBar.render");
var accountBar = _.template(this.template, this.model.toJSON());
this.parent.$el.append(accountBar);
return;
}
});
Catalog.DocumentsBrowserView = Backbone.View.extend({
el: $("#catalog"),
events: {
"click #new-document": "createDocument",
"click .open-document": "editDocument"
},
initialize: function () {
//_.bindAll(this, 'createDocument editDocument');
console.log("View - BrowseDocuments.initialize");
// template shoud be in the page wrapped inside this tag:
// <script id="template-test" type="text/template">...</script>
this.template = tmplDocumentsBrowser;
this.collection = new CatalogCollection.DocumentsList();
console.log(this.collection);
// data updates will be managed from Catalog.App
this.listenTo(this.collection, "add", this.render);
},
createDocument: function() {
console.log("View - BrowseDocuments.createDocument")
this.parent.createDocument();
},
editDocument: function() {
//var model = this.collection.get(1);
//console.log(model.name);
this.parent.editDocument(-1);
},
render: function() {
console.log("View - BrowseDocuments.render");
//console.log(this.collection.toJSON());
var documentsList = _.template(this.template, {documents:this.collection.toJSON()})
this.parent.$el.append(documentsList);
this.delegateEvents();
return;
}
});
// View for assets to place in the catalog will be managed by something like DocumentEditor
Catalog.AssetsBrowserView = Backbone.View.extend({
el: $("#catalog"),
events: {
"click .folder-closed > div": "openFolder",
"click .folder-opened > div": "statusClosedFolder"
},
initialize: function() {
console.log("View - AssetsBrowser.initialize");
//console.log(data);
this.collection = new CatalogCollection.AssetsList();
// set in openFolder to get where to place renderChildren
this.$currentTarget = null;
this.parentTreeId = false;
this.tmplAssetsNodes = tmplAssetsNodes;
this.tmplAssetsChildren = tmplAssetsChildren;
this.tmplDocumentName = tmplDocumentName;
// data updates will be managed from Catalog.App
this.listenToOnce(this.collection, "add", this.renderNodes);
this.listenTo(this.collection, "add", this.appendList);
},
openFolder: function(e) {
this.$currentTarget = $(e.currentTarget).parent();
//console.log("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ");
//console.log($(e.currentTarget).html());
if (this.$currentTarget.find(" > ul").length === 0) {
console.log("View - AssetsBrowser.openFolder currentTarget DOESN'T have children");
//console.log(this.$currentTarget.html());
this.parentTreeId = this.$currentTarget.data("id");
console.log(this.collection);
var item = this.collection.where({treeId: this.parentTreeId});
this.collection.url = item.url;
this.collection.fetch({success: function(){
console.log("got the data"); // => 2 (collection have been populated)
}});
this.statusLoadingFolder();
} else {
console.log("View - AssetsBrowser.openFolder currentTarget ALLREADY have children");
//console.log(this.$currentTarget.html());
this.statusOpenedFolder();
}
},
appendList: function (data) {
//this.fullCollection = this.fullCollection.push(data);
console.log("View - AssetsBrowser.appendList");
//console.log("data.length: " + data[0])
//var list = $.parseJSON();
//this.fullItemList = this.fullItemList.concat(this.collection.attributes);
},
statusLoadingFolder: function () {
console.log("View - AssetsBrowser.statusLoadingFolder");
// change it with a loader
this.$currentTarget.removeClass("folder-closed").addClass("folder-opened");
this.$currentTarget.find(".assets-sprite").removeClass("sprite-folder-closed").addClass("sprite-folder-opened");
},
statusOpenedFolder: function () {
// change the css selectors from closed tab to opened tab
console.log("View - AssetsBrowser.statusOpenedFolder");
this.$currentTarget.removeClass("folder-closed").addClass("folder-opened");
this.$currentTarget.find(".assets-sprite").removeClass("sprite-folder-closed").addClass("sprite-folder-opened");
},
statusClosedFolder: function (e) {
var $target = $(e.currentTarget).parent();
console.log("View - AssetsBrowser.statusClosedFolder");
//this.$currentTarget.find("ul").remove();
//console.log(this.$currentTarget);
$target.removeClass("folder-opened").addClass("folder-closed");
$target.find(".assets-sprite").removeClass("sprite-folder-opened").addClass("sprite-folder-closed");
},
renderDocumentName: function(data) {
var documentName = _.template(this.tmplDocumentName, data);
if (this.parent.$el.find("#catalog-name").length === 0) {
this.parent.$el.find("#assets").prepend(documentName);
} else {
this.parent.$el.find("#catalog-name").html(documentName);
}
},
renderNodes: function(data) {
console.log("View - AssetsBrowser.renderNodes");
//console.log(this.collection.attributes);
//this.appendList(this.collection.attributes);
this.listenTo(this.collection, "add", this.renderChildren);
//console.log("Catalog.AssetsBrowserView.renderNodes");
var assetsNodes = _.template(this.tmplAssetsNodes, {nodes:this.collection.toJSON()});
if (this.parent.$el.find("#assets-browser").length === 0) {
this.parent.$el.find("#assets").append(assetsNodes);
} else {
this.parent.$el.find("#assets-browser").html(assetsNodes);
}
this.delegateEvents();
return;
},
renderChildren: function() {
this.statusOpenedFolder();
var parentTreeId = this.parentTreeId;
_.each(this.collection.toJSON(), function (model) {
model.treeId = parentTreeId;
console.log(model);
});
//this.appendList(this.collection.attributes);
console.log("View - AssetsBrowser.renderChildren");
var assetsChildren = _.template(this.tmplAssetsChildren, {items:this.collection.toJSON()});
this.$currentTarget.find("ul").remove();
this.$currentTarget.append(assetsChildren);
this.delegateEvents();
//console.log(this.collection.toJSON());
return;
}
});
return Catalog;
}
);
这是我的视图
库
define([
'jquery',
'lodash',
'backbone'
],
function ($, _, Backbone) {
var CatalogModel = {};
CatalogModel.App = Backbone.Model.extend({
defaults: {
name: "Catalog without name",
userdata: false,
documents: false
},
initialize:function () {
console.log("Model - App.initialize");
this.on("change", function () {
console.log("Model - App.change");
});
},
url:"json/logged_data.json"
});
CatalogModel.User = Backbone.Model.extend({
defaults: {
username: "Default username"
},
initialize: function () {
console.log("Model - User.initialize");
this.on("change", function () {
console.log("Model - User.change");
});
}
});
CatalogModel.Document = Backbone.Model.extend({
defaults: {
name: "Default catalog name",
status: {
url: "#",
ready: false,
downloadableProductUrl: "#"
}
},
initialize: function () {
//console.log("CatalogModel.DocumentBrowse.initialize");
this.on("change", function () {
console.log("Model - Document.change");
});
}
});
CatalogModel.Asset = Backbone.Model.extend({
defaults: {
nodeType:"folder",
name:"Default folder name",
url:false,
treeId:"0",
collection:false
},
initialize: function () {
console.log("Model - Asset.initialize");
this.on("change", function () {
console.log("Model - Asset.change");
});
}
});
return CatalogModel;
}
);
define([
'jquery',
'lodash',
'backbone',
'app/models/catalog'
],
function ($, _, Backbone, CatalogModel) {
var CatalogCollection = {};
CatalogCollection.DocumentsList = Backbone.Collection.extend({
initialize: function () {
console.log("Collection - DocumentsList.initialize");
this.model = new CatalogModel.Document();
this.on("add", function () {
console.log("Collection - DocumentsList.add");
});
}
});
CatalogCollection.AssetsList = Backbone.Collection.extend({
initialize: function () {
console.log("Collection - AssetsList.initialize");
this.model = new CatalogModel.Asset();
this.on("add", function () {
console.log("Collection - AssetsList.change");
});
},
parse: function(response) {
console.log("Collection - AssetsList.parse");
//console.log(response);
return response;
},
url:"json/assets_nodes.json"
});
return CatalogCollection;
}
);
define([
'jquery',
'lodash',
'backbone',
'app/models/catalog',
'app/collections/catalog',
'libs/text!app/templates/account_bar.html',
'libs/text!app/templates/document_browser.html',
'libs/text!app/templates/document_editor.html',
'libs/text!app/templates/document_name.html',
'libs/text!app/templates/assets_nodes.html',
'libs/text!app/templates/assets_children.html'
// ,'libs/text!app/templates/assets_items.html'
],
function ($, _, Backbone, CatalogModel, CatalogCollection, tmplAccountBar, tmplDocumentsBrowser, tmplDocumentEditor, tmplDocumentName, tmplAssetsNodes, tmplAssetsChildren) {
var Catalog = {};
Catalog.App = Backbone.View.extend({
el: $("#catalog"),
initialize: function() {
console.log("View - App.inizialize");
this.tmplDocumentEditor = tmplDocumentEditor;
// here i'll set subviews for user bar, doc browser, assets list and book editor
this.UserBarSubView = new Catalog.UserBarView();
this.DocumentsBrowserSubView = new Catalog.DocumentsBrowserView();
this.AssetsBrowserSubView = new Catalog.AssetsBrowserView();
this.UserBarSubView.parent = this;
this.DocumentsBrowserSubView.parent = this;
this.AssetsBrowserSubView.parent = this;
this.model = new CatalogModel.App();
this.listenTo(this.model, "change", this.updateMainRequest);
this.model.fetch(null);
},
updateMainRequest: function(data){
var data = this.model.toJSON();
console.log("View - App.updateMainRequest");
//console.log(data.documents);
this.UserBarSubView.model.set(data.userdata);
var documents = [];
for (var i = data.documents.length - 1; i >= 0; i--) {
documents.push(new CatalogModel.Document(data.documents[i]));
};
this.DocumentsBrowserSubView.collection.set(documents);
},
createDocument: function() {
console.log("View - App.createDocument");
var name = this.model.get("name");
//console.log(name);
this.renderDocumentEditor(name);
},
editDocument: function(index) {
console.log("View - App.editDocument");
console.log(index);
},
renderDocumentEditor: function(name) {
console.log("View - App.renderDocumentEditor");
this.$el.find("#docs-browser").remove();
this.$el.append(this.tmplDocumentEditor);
this.AssetsBrowserSubView.renderDocumentName({name:name});
this.AssetsBrowserSubView.collection.fetch();
/*
this.$el.find("#assets").html("assets creato dinamicamente");
this.$el.find("#document-opened").html("doc opened creato dinamicamente");
*/
}
});
Catalog.UserBarView = Backbone.View.extend({
initialize: function() {
console.log("View - UserBar.inizialize");
this.template = tmplAccountBar;
this.model = new CatalogModel.User();
// data updates will be managed from Catalog.App
this.listenTo(this.model, "change", this.render);
},
render: function() {
console.log("View - UserBar.render");
var accountBar = _.template(this.template, this.model.toJSON());
this.parent.$el.append(accountBar);
return;
}
});
Catalog.DocumentsBrowserView = Backbone.View.extend({
el: $("#catalog"),
events: {
"click #new-document": "createDocument",
"click .open-document": "editDocument"
},
initialize: function () {
//_.bindAll(this, 'createDocument editDocument');
console.log("View - BrowseDocuments.initialize");
// template shoud be in the page wrapped inside this tag:
// <script id="template-test" type="text/template">...</script>
this.template = tmplDocumentsBrowser;
this.collection = new CatalogCollection.DocumentsList();
console.log(this.collection);
// data updates will be managed from Catalog.App
this.listenTo(this.collection, "add", this.render);
},
createDocument: function() {
console.log("View - BrowseDocuments.createDocument")
this.parent.createDocument();
},
editDocument: function() {
//var model = this.collection.get(1);
//console.log(model.name);
this.parent.editDocument(-1);
},
render: function() {
console.log("View - BrowseDocuments.render");
//console.log(this.collection.toJSON());
var documentsList = _.template(this.template, {documents:this.collection.toJSON()})
this.parent.$el.append(documentsList);
this.delegateEvents();
return;
}
});
// View for assets to place in the catalog will be managed by something like DocumentEditor
Catalog.AssetsBrowserView = Backbone.View.extend({
el: $("#catalog"),
events: {
"click .folder-closed > div": "openFolder",
"click .folder-opened > div": "statusClosedFolder"
},
initialize: function() {
console.log("View - AssetsBrowser.initialize");
//console.log(data);
this.collection = new CatalogCollection.AssetsList();
// set in openFolder to get where to place renderChildren
this.$currentTarget = null;
this.parentTreeId = false;
this.tmplAssetsNodes = tmplAssetsNodes;
this.tmplAssetsChildren = tmplAssetsChildren;
this.tmplDocumentName = tmplDocumentName;
// data updates will be managed from Catalog.App
this.listenToOnce(this.collection, "add", this.renderNodes);
this.listenTo(this.collection, "add", this.appendList);
},
openFolder: function(e) {
this.$currentTarget = $(e.currentTarget).parent();
//console.log("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ");
//console.log($(e.currentTarget).html());
if (this.$currentTarget.find(" > ul").length === 0) {
console.log("View - AssetsBrowser.openFolder currentTarget DOESN'T have children");
//console.log(this.$currentTarget.html());
this.parentTreeId = this.$currentTarget.data("id");
console.log(this.collection);
var item = this.collection.where({treeId: this.parentTreeId});
this.collection.url = item.url;
this.collection.fetch({success: function(){
console.log("got the data"); // => 2 (collection have been populated)
}});
this.statusLoadingFolder();
} else {
console.log("View - AssetsBrowser.openFolder currentTarget ALLREADY have children");
//console.log(this.$currentTarget.html());
this.statusOpenedFolder();
}
},
appendList: function (data) {
//this.fullCollection = this.fullCollection.push(data);
console.log("View - AssetsBrowser.appendList");
//console.log("data.length: " + data[0])
//var list = $.parseJSON();
//this.fullItemList = this.fullItemList.concat(this.collection.attributes);
},
statusLoadingFolder: function () {
console.log("View - AssetsBrowser.statusLoadingFolder");
// change it with a loader
this.$currentTarget.removeClass("folder-closed").addClass("folder-opened");
this.$currentTarget.find(".assets-sprite").removeClass("sprite-folder-closed").addClass("sprite-folder-opened");
},
statusOpenedFolder: function () {
// change the css selectors from closed tab to opened tab
console.log("View - AssetsBrowser.statusOpenedFolder");
this.$currentTarget.removeClass("folder-closed").addClass("folder-opened");
this.$currentTarget.find(".assets-sprite").removeClass("sprite-folder-closed").addClass("sprite-folder-opened");
},
statusClosedFolder: function (e) {
var $target = $(e.currentTarget).parent();
console.log("View - AssetsBrowser.statusClosedFolder");
//this.$currentTarget.find("ul").remove();
//console.log(this.$currentTarget);
$target.removeClass("folder-opened").addClass("folder-closed");
$target.find(".assets-sprite").removeClass("sprite-folder-opened").addClass("sprite-folder-closed");
},
renderDocumentName: function(data) {
var documentName = _.template(this.tmplDocumentName, data);
if (this.parent.$el.find("#catalog-name").length === 0) {
this.parent.$el.find("#assets").prepend(documentName);
} else {
this.parent.$el.find("#catalog-name").html(documentName);
}
},
renderNodes: function(data) {
console.log("View - AssetsBrowser.renderNodes");
//console.log(this.collection.attributes);
//this.appendList(this.collection.attributes);
this.listenTo(this.collection, "add", this.renderChildren);
//console.log("Catalog.AssetsBrowserView.renderNodes");
var assetsNodes = _.template(this.tmplAssetsNodes, {nodes:this.collection.toJSON()});
if (this.parent.$el.find("#assets-browser").length === 0) {
this.parent.$el.find("#assets").append(assetsNodes);
} else {
this.parent.$el.find("#assets-browser").html(assetsNodes);
}
this.delegateEvents();
return;
},
renderChildren: function() {
this.statusOpenedFolder();
var parentTreeId = this.parentTreeId;
_.each(this.collection.toJSON(), function (model) {
model.treeId = parentTreeId;
console.log(model);
});
//this.appendList(this.collection.attributes);
console.log("View - AssetsBrowser.renderChildren");
var assetsChildren = _.template(this.tmplAssetsChildren, {items:this.collection.toJSON()});
this.$currentTarget.find("ul").remove();
this.$currentTarget.append(assetsChildren);
this.delegateEvents();
//console.log(this.collection.toJSON());
return;
}
});
return Catalog;
}
);
在我的App.renderDocumentEditor
view方法中,我的集合似乎有问题
renderDocumentEditor: function(name) {
console.log("View - App.renderDocumentEditor");
this.$el.find("#docs-browser").remove();
this.$el.append(this.tmplDocumentEditor);
this.AssetsBrowserSubView.renderDocumentName({name:name});
// collection.fetch() throws Uncaught TypeError: object is not a function
this.AssetsBrowserSubView.collection.fetch();
}
我在这里遇到了同样的问题,我通过将json
数组的每个元素设置到集合中模型中for
语句解决了这个问题:
updateMainRequest: function(data){
var data = this.model.toJSON();
console.log("View - App.updateMainRequest");
//console.log(data.documents);
this.UserBarSubView.model.set(data.userdata);
var documents = [];
for (var i = data.documents.length - 1; i >= 0; i--) {
documents.push(new CatalogModel.Document(data.documents[i]));
};
this.DocumentsBrowserSubView.collection.set(documents);
}
可能我在如何使用集合
方面遗漏了一些东西,我不敢相信在使用集合
方法集合
之前,我必须将传递到模型
实例中的数组的每个元素都设置好
如果是,我应该如何处理集合的响应。将请求提取到服务器?您只是误解了主干集合的模型
键。它应该是一个模型,不是模型的一个实例。因此:
this.model = new CatalogModel.Asset();
应该是
this.model = CatalogModel.Asset;
(因此没有理由将其放入initialize
方法)
现在,说说为什么。目标是为主干集合(其模型的构造函数)提供模型,以便它们可以执行您不允许它们执行的操作:将对象转换为模型。
您肯定已经意识到您的未捕获类型错误:对象不是函数
的来源:当您使用set
或fetch
时,主干正在尝试使用model
键的值:var model=new this.model(attrs,options)代码>。在您的例子中,this.model
只是一个对象,因此new
操作符自然会抛出一个错误,告诉您试图将其用于对象而不是函数。您只是误解了主干集合的model
键。它应该是一个模型,不是模型的一个实例。因此:
this.model = new CatalogModel.Asset();
应该是
this.model = CatalogModel.Asset;
(因此没有理由将其放入initialize
方法)
现在,说说为什么。目标是为主干集合(其模型的构造函数)提供模型,以便它们可以执行您不允许它们执行的操作:将对象转换为模型。
您肯定已经意识到您的未捕获类型错误:对象不是函数
的来源:当您使用set
或fetch
时,主干正在尝试使用model
键的值:var model=new this.model(attrs,options)代码>。在您的例子中,this.model
只是一个对象,因此new
操作符自然会抛出一个错误,告诉您试图将其用于对象,而不是函数。感谢您的解释,现在在我的控制器中,我还有model:CatalogModel.Asset
在初始化
之外,在我的视图中,我在需要的地方更改了collection:CatalogCollection.DocumentsList
或model
。不幸的是,现在似乎什么都不起作用了,我得到了对象函数(){returni.apply(this,arguments)}没有方法“on”
,就像没有集合的实例一样。我注意到他们使用了主干集合的新实例:app.todos=newtodolist()代码>如何修复此问题?好吧,也许我知道了,你的意思是我需要在控制器中设置模型,但我需要在视图中创建实例,因为我在视图中链接了它们?我希望我得到了@VittorioVittori很抱歉回复得太晚,但是是的,在视图中,您使用实例是因为您实际表示数据(来自模型或集合)。在集合中,您只需要模型类型就可以从对象创建新模型。这是一个不同的用途。感谢您的解释,现在在我的控制器中,我有模型:目录模型。资产
在初始化
之外。此外,在我的视图中,我在需要的地方更改了集合:目录集合。文档列表
或模型
。不幸的是,现在似乎什么都不起作用了,我得到了对象函数(){returni.apply(this,arguments)}没有方法“on”
,就像没有集合的实例一样。我注意到他们使用了主干集合的新实例:app.todos=newtodolist()代码>如何修复此问题?好吧,也许我知道了,你的意思是我需要在控制器中设置模型,但我需要在视图中创建实例,因为我在视图中链接了它们?我希望我得到了@VittorioVittori很抱歉回复得太晚,但是是的,在视图中,您使用实例是因为您实际表示数据(来自模型或集合)。在集合中,您只需要模型类型就可以从对象创建新模型。那是另一个用途。