在我的骨干.Marionette应用程序我有一个模型,需要一个Id属性来构建它的URL。因此,我通过传递一个Id来创建模型,将其添加到视图中然后获取模型:
model = new Model({_id:id})
view = new View({model:model})
app.content.show(view)
model.fetch()
我希望视图只在获取模型后才开始渲染,但Marionette会立即渲染模型,导致我的模板渲染失败,因为预期的属性不存在。任何解决方法?
我正在尝试做类似于接受的答案: Binding a Backbone Model to a Marionette ItemView - blocking .fetch()?
但是,虽然这与骨干有关,但正如答案中所述,Marionette会自动呈现视图。
答案 0 :(得分:10)
以上两个答案都有效。
这是我喜欢使用的另一种方式(感觉更多 backboney )。
将视图直接绑定到模型
获取模型完成后,您指定的函数将运行。
这可以使用模型或集合来完成。
var Model = Backbone.Model.extend({});
var model = new Model();
model.fetch();
var View = Marionette.ItemView.extend({
model:model,
initialize: function(){
this.model.bind("sync", this.render, this);// this.render can be replaced
} // with your own function
});
app.region.show(new View);
这也使您可以随时获取。
答案 1 :(得分:7)
如果你真的想要在获取模型之前阻止渲染,你应该重新排序你的调用:
model = new Model({_id:id});
view = new View({model:model});
model.fetch({success: function () {
app.content.show(view);
});
或者,您应该考虑立即渲染并利用Marionette的空白状态支持。
答案 2 :(得分:2)
基于Derick Bailey的一个例子:
model = new Model({_id:id})
var fetched = model.fetch();
// wait for the model to be fetched
$.when(fetched).then(function(){
view = new View({model:model})
app.content.show(view)
});
答案 3 :(得分:1)
我很快就遇到了同样的问题并决定使用Marionette的事件系统来让视图在触发show()之前传达其状态。我也使用requireJS,这增加了一些额外的复杂性 - 但这种模式有帮助!
我有一个带有UI元素的视图,当点击它时,会触发一个事件来加载一个新视图。这可能是子视图或导航视图 - 无关紧要。
App.execute('loadmodule:start', { module: 'home', transition: 'left', someOption: 'foo' });
该事件被Wreqr' setHandlers'捕获。并触发视图加载序列(在我的情况下,我做了一堆逻辑来处理状态转换)。 '开始'序列进入新视图并传递必要的选项。
var self = this;
App.commands.setHandlers({'loadmodule:start': function( options ) { self.start( options );
然后,视图获取加载处理集合/模型并获取初始化。视图侦听模型/集合更改,然后触发新的" ready"使用wreqr的executre命令的事件。
this.listenTo( this.model, 'change', function(){
App.execute('loadmodule:ready', { view: this, options: this.options });
});
我有一个不同的处理程序捕获那个就绪事件(和选项,包括视图对象引用)并触发show()。
ready: function( options ) {
// catch a 'loadmodule:ready' event before proceeding with the render / transition - add loader here as well
var self = this;
var module = options.options.module;
var view = options.view;
var transition = options.options.transition;
var type = options.options.type;
if (type === 'replace') {
self.pushView(view, module, transition, true);
} else if (type === 'add') {
self.pushView(view, module, transition);
} else if (type === 'reveal') {
self.pushView(view, module, transition, true);
}
},
pushView: function(view, module, transition, clearStack) {
var currentView = _.last(this.subViews);
var nextView = App.main.currentView[module];
var self = this;
var windowheight = $(window).height()+'px';
var windowwidth = $(window).width()+'px';
var speed = 400;
switch(transition) {
case 'left':
nextView.show( view );
nextView.$el.css({width:windowwidth,left:windowwidth});
currentView.$el.css({position:'absolute',width:windowwidth,left:'0px'});
nextView.$el.animate({translate: '-'+windowwidth+',0px'}, speed, RF.Easing.quickO);
currentView.$el.animate({translate: '-'+windowwidth+',0px'}, speed, RF.Easing.quickO, function(){
if (clearStack) {
_.each(_.initial(self.subViews), function( view ){
view.close();
});
self.subViews.length = 0;
self.subViews.push(nextView);
}
});
break;
我会尝试写出整个系统的一个好主意,并在下周左右发布。