假设我有一个像这样的JSON:
JSON示例,我的json在jsonlint上验证并且可以正常工作。
json_object = {
"texts_model": {
"hello": "hola",
"icon_text": "Icon!"
},
"collection_vias": {
"text": "hola",
"icon_text": "Icon!"
}
};
我创建了一个Collection来解析json的内容,并从这个json生成模型和集合。
App.TemplatesCollection = Backbone.Model.extend({
model: App.TemplateModel,
url: TEMPLATES_SERVICE,
initialize: function(){
this.fetch({
success: (function () {
console.log(' Success ');
}),
error:(function (e) {
//console.log(' Error: ' + e);
}),
complete:(function (e) {
console.log(' Fetch completado con exito. ');
})
});
},
//Here i generate all my models and collections.
parse: function(response){
App.texts = new App.TemplateModel(response.text_model);
App.vias = new App.ViasCollection(response.collection_vias);
return response;
},
//I was trying with the get function but i the only thing i got was undefined.
plain_texts: function(){
return( this.get('plain_texts') ) ;
}
});
视图是这样的:
App.TemplateView = Backbone.View.extend({ el:App。$ main_content, initialize:function(){ _.bindAll(this,' render'); }, //这里我传递了我要渲染的模板(html源代码)。 渲染:function(template){ var html = render(template,this.model.toJSON()); 应用$ main_content.html(HTML)。 归还这个; } });
我的start.js在那里他们生活了我的模型和视图的所有声明:
//应用 App = {
init: function(){
console.log('Iniciando...');
//variables y constantes
App.$main_content = $('#main-content-content');
App.$main_header = $('#main-header-content')
App.$main_navigation = $('#main-navigation-content');
//data
App.templates = new App.TemplatesCollection();
//views
App.templateView = new App.TemplateView({model: App.texts});
//router
App.router = new App.Router();
},
start: function(){
//init
App.init();
//router
Backbone.history.start();
}
}
路由器:
//路由器 App.Router = Backbone.Router.extend({
routes:{
"" : "index",
":web" : "url"
},
index: function(){
console.log("index");
//Here i do not know what to do, i mean do i have to instiate the View each time i go to index? or only render?
App.templateView = new App.TemplateView({model: App.texts});
App.templateView.render("sections/login/form");
},
url: function(web){
console.log(web);
}
});
//on document ready
$(function(){
App.start();
});
我的问题是,当加载html时,我唯一拥有的是: "未捕获的TypeError:无法调用方法' toJSON'未定义"
但是当我把它放在开发者控制台上时:
App.templateView = new App.TemplateView({model: App.texts});
App.templateView.render("sections/login/form");
我的观点正确呈现。
为什么我的视图不会在加载时呈现,只有当我将代码放在开发者控制台上时才会显示?
如何在路由器URL上的视图上渲染我的模型? 为什么我在开发者控制台上加载的html上有未定义的内容?
---- --- EDIT
好的,
我想我明白了。也许我会产生一个没有问题的问题。
现在我的模型是这样的:
App.TemplatesCollection = Backbone.Model.extend({
model: App.TemplateModel,
url: TEMPLATES_SERVICE,
plain_texts: function(){
return this.get('texts') ;
},
initialize: function(){
this.fetch();
}
});
观点:
App.TemplateView = Backbone.View.extend({
el: App.$main_content,
initialize: function(){
console.log(this.collection);
var ea = this.collection.get('texts');
console.log(ea);
},
render: function(template){
console.log(this.collection);
return this;
}
});
现在我在我的视图中看到了我的收藏。
但是,当我尝试这样做只获取我的视图上的文本版本时:
var ea = this.collection.get('texts');
console.log(ea);
我得到了未定义的错误:
未捕获的TypeError:无法调用方法' get'未定义的
关于如何解决这个问题的任何想法?
我试图自己解决这个问题。我不想看起来像是要求开发我的解决方案。
提前致谢。
答案 0 :(得分:0)
这有点难以阅读,但是快速浏览一下:你的App.texts =在你的Collection的parse()函数中。结果,一旦执行了集合上的.fetch()就会调用它......直到那时,你的App.texts是未定义的!
如果在创建TemplateView时未定义App.texts,那么视图的模型实际上将是未定义的,因此,在渲染中,当您使用的模板引擎正在执行toJSON()时,它会说它具有未定义的值......
可能还有其他问题,但这个问题最明显。这是一个快速和彻底的修复:一旦fetch()完成,您的集合将触发重置事件。这是你做渲染的提示。因此,您可以做的是,不是将模型传递给View,而是可以传递集合:
App.templateView = new App.TemplateView({collection: App.templates});
现在,在View的初始化中,您可以执行以下操作:
if(App.texts) {
//Your collection has already fetched and already went through parse()
this.model = App.texts;
this.render("sections/login/form");
} else {
//Your collection hasn't done the fetch yet
view = this;
this.collection.one("reset", function(){
view.model = App.texts;
view.render("sections/login/form");
});
}
如果您将一个集合作为View的构造的参数,它将存储在this.collection中,与模型相同。这里的想法是使用事件来知道何时进行渲染,并让视图告诉您何时可以渲染。您还可以在render()函数中执行某些操作来检查模型是否已定义!
要查看此分析是否正确,您可以放置console.log(App.texts);在路由器的索引函数中。
使代码更明显的一种方法是直接在App的init中初始化App.texts和App.vias。如果你真的需要在AppTemplates的fetch()的解析中加载它们,请将它们引用到你的AppTemplatesCollection。不同之处在于您可以绑定App.vias集合中的事件('add','remove','reset')或App.texts模型('change')。
我注意到的另一件事是你有一个App.TemplateModel的集合,但是你仍在创建一个App.texts,你把fetch的结果放到你自己的App.TemplateModel实例中?这似乎不对,也许你有理由这样做,但在最一般的情况下,该集合假设处理模型的创建,特别是在获取之后!
parse()方法的通常用例是侧载数据(其他模型/集合),更改格式(从XML到JS可以理解的东西)或删除无用的键(例如user:{id :...,name:...},你将返回response.user,以便Backbone可以直接使用正确的哈希)。你在这里做的事情似乎不属于这种模式,所以可能会引起担忧?
答案 1 :(得分:0)
在您的代码中,您创建了collection
:
App.TemplatesCollection = Backbone.Model.extend({
//rest of the code
如果您想创建collection
,则需要展开{{1}}而不是Backbone.Collection
。
Backbone.Model