2012-08-22 27 views
2

在Backbone的数据驱动范例中,骨干视图/路由器应订阅模型更改并根据模型更改事件进行操作。遵循这个原则,应用程序的视图/路由器可以相互隔离,这非常棒。backbone.js和不在模型中的状态

但是,在模型中没有保留的应用程序的状态有很多变化。例如,在待办应用程序中,可能会有按钮让您查看“已完成”,“未完成”或“全部”任务。这是一个应用程序状态,不会在模型中持久化。请注意,任何任务的完成状态都会持续存在,但视图中的当前过滤器是暂态状态。

什么是处理这种应用程序状态的好方法?使用普通的非主干状态意味着视图/路由器不能监听这种状态的变化,因此很难在数据驱动范例中编码。

回答

2

您的按钮过滤器示例可以使用正确解决模型事件

我想你的按钮处理程序有权访问任务集合。然后过滤收集和触发事件在选择模型像:

model.trigger("filter:selected") 

model.trigger("filter:un-selected") 

模型视图可以听其型号这些事件,并采取相应的行动。

这也是继你的尊重不使用或选择“不属于持久属性”的要求,但我没有任何创伤,使用特殊的属性,即使它们不应该是持久的。所以我也建议修改选择属性的模型来表示挥发性状态。

所以在你按钮处理程序过滤收集和修改选择属性,在模型是我的首选解决方案:

model.set("selected", true) 

你总是可以覆盖Model.toJSON()sync前清理或刚刚离开这个特殊属性前往您的服务器并在那里被忽略。

+0

这是一个很好的答案。谢谢。 –

0

评论时间长了,所以我会产生第二个答案来比较。

首先,我觉得“完成”,“未完成”完全是项目模型属性,将被持续。或者,如果你的物品被许多用户所拥有,每个用户都有自己的“已完成”“未完成”状态,那么该物品将有一个completedState子模型或其他东西。要指出的是,虽然@fguillen为您提供了两种可能的解决方案,但我也更愿意以他的第二种方式来完成这一任务,模型包含属性和执行大部分工作的按钮/视图。

对于我来说,模型没有意义为此拥有自己的自定义事件。听起来像一个过滤器按钮只需要处理提供适当的意见。 (显示哪些项目)因此,我只是让button元素调用一个函数,它可以或多或少地直接在集合上运行过滤器。

event: { 
    'click filterBtnCompleted':'showCompleted' 
}, 
showCompleted: function(event) { 
    var completedAry = this.itemCollection.filter(function(item) { 
     return item.get('completed'); 
    }); 

    // Code empties your current item views and re-renders them with just filtered models 
} 

我倾向于弄走这几样方便的过滤功能集合中的自己,让我可以叫:

this.ItemCollection.getCompleted(); // etc. 

在模型中留下这些属性,忽视他们对你的服务器是好的。尽管如此,它听起来像是你想要坚持的属性。

还有一件事,你说用简单的非骨干国家牺牲事件。 (咧嘴:-)不是这样!您可以轻松扩展任何对象以具有Backbone.Event功能。

var flamingo = {}; 

_.extend(flamingo, Backbone.Events); 

现在你可以有火烈鸟触发器,并听取事件像其他任何事情!

编辑:解决路由器>查看数据往来------------------- //

我怎么做我的路由器可能不是什么你这样做,但我把我的appView作为选项传入路由器。我在appView中有一个名为showView()的函数,它可以创建子视图。因此,我的路由器可以直接访问我正在处理的视图。

// Router 
initialize: function(options) { 
    this.appView = options.appView; 
} 

在我们的例子中,它可能是itemsView需要过滤来呈现完成的项目。注意:我也有一个showView()函数来管理子视图。您可能只是在您的场景中直接使用appView。

所以当像/ items /#完成的路由被调用时,我可能会这样做。

routes: { 
    'completed':'completed' 
}, 
completed: { 
    var itemsView = ItemCollectionView.create({ 
     'collection': // Your collection however you do it 
    }); 
    this.appView.showView(itemsView); 

    itemsView.showCompleted(); // Calls the showCompleted() from View example way above 
} 

这有帮助吗?

+0

谢谢你的深思熟虑的回应! 我在问的是:想象一下用户输入“http://site.com/tasks#completed”,你现在需要显示所有完成的任务。您的路线处理程序如何通知您的视图? –

+1

它绝对有帮助;谢谢。我看到这种方法很多(也有相反的方法 - 传递路由器查看并让视图监听路由事件),但是我相信这两种方法都会打破路由器和视图之间应该彼此隔离的关注点分离原则。 –