我有一个Backbone SAP,它在主App视图中有两个子视图。这些是相互依赖的:顶部显示使用Vexflow(Javascript音乐符号包)呈现的乐谱,而另一个显示分数的分析,也使用Vexflow但使用一些额外的对象(文本,线条,可点击元素等。)
我遇到的主要问题是,在渲染得分视图之前,分析视图所需的大量数据才会出现。例如,音符的x坐标仅在绘制了音符后才可用(y坐标不同)。以下是(在示意图中)我的应用视图的设置方式:
var AppView = Backbone.View.extend({
//...
initialize: function() {
this.scoreView = new ScoreView();
this.analysisView = new AnalysisView({
data: this.getAnalysisData()
});
},
render: function() {
this.scoreView.render();
this.analysisView.render();
return this;
},
getAnalysisData: function() {
// Performs anaysis of this.scoreView,
// and returns result.
}
});
我的工作是在渲染得分视图后将分析视图设置移动到渲染方法中。我不喜欢这样做,因为getAnalysisData
方法可能非常昂贵,我相信渲染方法应该仅用于渲染事物而不是处理。
所以我想知道是否 - 因为似乎没有Vexflow解决方案 - 有一个可能解决这个问题的Backbone模式。我熟悉用于解耦视图的'pub / sub'事件聚合器模式,如:
this.vent = _.extend({}, Backbone.Events);
因此,在此模式下,分析视图render方法订阅渲染得分视图后触发的事件。但是,我不确定这会如何改变我的代码。或者也许使用listenTo
,如下所示:
// Score subview.
var ScoreView = Backbone.View.extend({
initialize: function() {
this.data = "Some data";
},
render: function() {
alert('score');
this.trigger('render');
}
});
// Analysis subview.
var AnalysisView = Backbone.View.extend({
initialize: function(options) {
this.data = options.data;
},
render: function() {
alert(this.data);
return this;
}
});
// Main view.
var AppView = Backbone.View.extend({
el: "#some-div",
initialize: function() {
this.scoreView = new ScoreView();
var view = this;
this.listenTo(this.scoreView, 'render', this.doAnalysis); // <- listen to 'render' event.
},
render: function() {
this.scoreView.render();
return this;
},
doAnalysis: function() {
this.analysisView = new AnalysisView({
data: this.getAnalysisData()
});
this.analysisView.render();
},
getAnalysisData: function() {
return this.scoreView.data;
}
});
当然,分析步骤仍然在渲染过程中有效地完成,但这似乎是一个更好的模式。它似乎更像是Backbone的做事方式。我对吗?或者我错过了什么?
修改:我必然必须在doAnalysis
中创建分析视图,我仍然可以在主视图initialize
中执行此操作(此刻我不是)。但是doAnalysis
已经在分数视图呈现后运行,否则无法访问相关的分数几何信息。