我正在开发一个Backbone
带有库的应用程序RequireJS
,lo-dash
一切正常,但在为我的对象设置json
数据时遇到问题。Collection
配置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>
这是我的Model
图书馆
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;
}
);
这是我的Collection
图书馆
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;
}
);
这是我的Views
图书馆
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;
}
);
这是我的控制台日志:
View - BrowseDocuments.render catalog.js:126
View - BrowseDocuments.createDocument catalog.js:117
View - App.createDocument catalog.js:54
View - App.renderDocumentEditor catalog.js:64
Collection - AssetsList.parse catalog.js:30
Uncaught TypeError: object is not a function
看来Collection
我的App.renderDocumentEditor
视图方法有问题。
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
Array
到它的Collection
inModel
语句中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);
}
可能我错过了应该如何使用的东西,我不敢相信在使用方法之前Collection
我必须将数组的每个元素设置为Model
实例。Collection
set
如果是,我应该如何处理对Collection.fetch
服务器的请求响应?