Javascript 如何使用pubsub和backbone.js聚合事件数据?
我正在用backbone.js构建一个小型的预订计算器,它主要基于操作静态数据集来响应用户输入。我将应用程序划分为不同的组件,如:Javascript 如何使用pubsub和backbone.js聚合事件数据?,javascript,jquery,backbone.js,Javascript,Jquery,Backbone.js,我正在用backbone.js构建一个小型的预订计算器,它主要基于操作静态数据集来响应用户输入。我将应用程序划分为不同的组件,如: 包裹 历法 票 总体成本视图 最后一个组件是最重要的。它根据上述列表中提到的其他组件发布的事件数据输出预订的最终成本。现在,我使用一个简单的jQuery发布子实现作为我的全局事件总线: /* jQuery Tiny Pub/Sub - v0.7 - 10/27/2011 * http://benalman.com/ * Copyright (c) 2011
/* jQuery Tiny Pub/Sub - v0.7 - 10/27/2011
* http://benalman.com/
* Copyright (c) 2011 "Cowboy" Ben Alman; Licensed MIT, GPL */
var o = $({});
$.subscribe = function() {
o.on.apply(o, arguments);
};
$.unsubscribe = function() {
o.off.apply(o, arguments);
};
$.publish = function() {
o.trigger.apply(o, arguments);
};
除一件事外,这很有效:我无法访问计算最终totalCost
所需的聚合数据
因此,当我发布这样的事件时:
var SelectListView = Backbone.View.extend({
events: {
'change': 'pkgSelected'
},
pkgSelected: function(ev){
$.publish('pkg/changed', selectedPkg);
},
});
$.subscribe('pkg/changed', _.bind(this.updatePackageAmount, this));
我是这样订阅的:
var SelectListView = Backbone.View.extend({
events: {
'change': 'pkgSelected'
},
pkgSelected: function(ev){
$.publish('pkg/changed', selectedPkg);
},
});
$.subscribe('pkg/changed', _.bind(this.updatePackageAmount, this));
我获取当前选定的包数据。问题是我无法获取应用程序其他部分正在发布的数据,如:
$.publish('car/selected', selectedCar);
$.publish('numTickets/changed', ticketData);
我无法将所有数据汇总到一个地方进行计算,例如:
updatePackageAmount: function(ev, numTickets, travelCost, currentDate){ // I need the data passed in as parameters to be always fresh
var totalCost = parseInt(cost * numTickets, 10) + parseInt(travelCost, 10);
this.render(totalCost);
},
如何在一个组件不知道另一个组件的情况下聚合数据?我应该使用某种合理的全局应用程序对象来存储这些公共共享数据吗?如果是这样,我将如何执行此操作?自主干v0.9.9以来,全局
主干.Events
对象具有
混合在一起,这样你就可以
将该对象用作全局事件总线。这是一种很常见的模式
某种全球事件总线将您的所有行为联系在一起。没有一个,,
我认为你只需要创建一种所有权层次结构
更高级别的对象从其子对象引发事件并触发事件
从更高的层次对他们的孩子
我认为在小型应用程序中,事件总线方法可能更容易处理:
var SelectListView = Backbone.View.extend({
events: {
'change': 'pkgSelected'
},
pkgSelected: function(ev){
// : is commonly used for event namespacing in Backbone, but feel
// free to keep using /
Backbone.Events.trigger('pkg:change', selectedPkg);
},
});
// Your total view
var SomeOtherView = Backbone.View.Extend({
initialize: function() {
var _this = this;
// If you use listenTo, the event listener will automatically be
// disabled when your view is removed
this.listenTo(Backbone.Events, 'pkg:change', function(selectedPkg) {
_this.selectedPkg = selectedPkg;
});
}
)};
你甚至可以用一个
存储所有选项的结果:控制器可以侦听
在主干上的更改。事件,在模型本身上设置适当的字段,
然后,视图可以侦听模型上的更改事件并重新渲染
视情况而定
反正,
提供合适的全局应用程序对象(),该对象
可能适用于您的案例(除了许多其他非常好的组件
为了构建主干应用程序。为了一致性,你可以考虑使用一个带有<代码>主干的对象。事件< /C> >作为事件总线而不是jQuery对象混合。你能告诉我如何吗?还告诉我这将如何解决我的数据聚合问题?它不一定对聚合位有帮助,这就是为什么我没有把它放在答案中的原因。纯粹是一个建议:因为主干有自己的事件语义,所以可能会减少认知开销。有关示例,请参见。从v0.9.9开始,您还可以将全局
主干.Events
对象用作事件总线。由于我使用的是静态不可变数据集,因此所有模型实际上都没有改变。在上述情况下,用户选择不同的包。那么我应该在模型中设置哪些字段呢?另外,如何跨组件聚合来自多个事件的数据?单击事件发送数据,然后用户下次从下拉列表中选择包时,该数据将丢失?如何始终保持旧的点击数据?模型不一定要表示您的数据,但它可以是存储UI状态的有用方法。啊!你的意思是,如果我将ui状态存储为{'selected':true}?对。您可以使用一个模型,该模型中的字段如pkgSelected
,numTickets
,用户界面可以更改。当您使用Model.set
更改字段时,将触发一个更改事件(如change:pkgSelected
),您的总视图可以侦听该事件,并在需要时重新渲染。嗯……将尝试Wyatt