我正在开发一个小型骨干应用程序。
我目前遇到的问题是我想显示特定项目的配置文件。
当我单击列表项时会触发此 showProfile 事件。不是 showProfile 事件需要通知父 listView 通知上面的 sidebarView 通知 mainView 现在可以实例化 profileView。
这将涉及事件链中的三到四个视图。这个问题有可能的解决方法吗?
问候, 博多
我正在开发一个小型骨干应用程序。
我目前遇到的问题是我想显示特定项目的配置文件。
当我单击列表项时会触发此 showProfile 事件。不是 showProfile 事件需要通知父 listView 通知上面的 sidebarView 通知 mainView 现在可以实例化 profileView。
这将涉及事件链中的三到四个视图。这个问题有可能的解决方法吗?
问候, 博多
我不知道这是否是最好的方法,但是对于这种情况,我通过创建一个具有扩展 Backbone.Events 的事件属性的对象来使用应用程序级事件聚合器。
我也倾向于使用相同的对象来存储应用程序范围的设置:
var app = {
settings: {},
events: _.extend({}, Backbone.Events),
};
然后,您可以从您的视图中触发一个 showProfile 事件并绑定到您的 mainView 中的 app.event,而无需在所有父视图中冒泡。
使用 RequireJS 时,我创建了一个应用程序模块,它是我的视图的依赖项:
define([
"jquery",
"underscore",
"backbone"
],
function($, _, Backbone) {
var app = {
root: "/",
settings: {},
events: _.extend({}, Backbone.Events),
};
return app;
});
我也倾向于将我的路由器放在 app 对象上,以防我需要在视图中访问它,所以在我的 main.js 中(如在主干样板中):
require([
"app",
"router",
],
function(app, Router) {
app.router = new Router();
Backbone.history.start({ pushState: true, root: app.root });
});
您可能想阅读 Derick Bailey 关于事件聚合器的博客文章:
同意,这类事情涉及很多样板。我尝试过的一种方法是通过使用(视图)方法来最小化这种情况,例如下面定义的方法:
/**
* Helper to facilitate event-bubbling, that is to say, the scenario where a view
* binds a callback to a child-View event only to retrigger it, mimicking the
* inherent event bubbling mechanism of the DOM. Allows renaming of the bubbled
* event as well as modification of the bubbled arguments
*
* @param view The View-dispatcher of the event
* @param ev Name of the event to bubble
* @param opts A hash of options where:
* bubbleName: New name of the event to bubble in case the event should be
* renamed. Optional
* args: The arguments to bubble:
* - When absent, the original arguments will be bubbled.
* - When set to a non-function value or an array-of-values, this value or
* values will be bubbled
* - When set to a function, it will be invoked on the incoming arguments and
* its returned value will be treated as in the previous case.
*/
bubbleEvent: function (view, ev, opts) {
if (!opts) { opts = {}; }
view.bind(ev, function () {
var inArgs = _.toArray(arguments),
bubbleArgs = _.isFunction(opts.args) ?
opts.args.apply(this, inArgs) : (opts.args || inArgs),
bubbleName = opts.bubbleName || ev;
this.trigger.apply(this, [bubbleName].concat(bubbleArgs));
}, this);
}
这将是 BaseView 的成员函数,您的所有其他视图都将扩展它。因此,它将在应用程序的每个视图中都可用。因此,为了让 ParentView 简单地冒泡由拥有的 childView 触发的事件,您只需要
bubbleEvent(childView, "event");
不过,这引入了一些样板,所以我也有兴趣看到这个问题的其他解决方案。