我们有一个大型木偶应用程序,它使用Backbone.trackit
来监控模型中未保存的更改。
我们现在有一些嵌套模型,实际上我们有一个模型集合,其中包含模型集合。
当子模型发生变化时, trackit
不支持将顶级模型标记为“脏” - 因为骨干不会冒这些变化事件。
我知道我们可以手动监控这些变更事件,但我正在寻找通用解决方案。
有没有人有过以下libs或其他任何解决方案的经验?
立即要求让trackit
使用嵌套事件 - 但是我找不到任何添加此内容的trackit
分支。
所以我想知道是否有人接触过这个,或者将上述lib与trackit
结合使用?
理想情况下,如果某个库会在链中一直触发标准的“更改”事件,那么trackit
就会接受这个并开始工作。
因此,如果model.countries[3].regions[4].name
发生了更改,则会在change:countries
上触发model
事件。因此,如果模型已经trackit
接受了,那么一切都会正常工作!
答案 0 :(得分:0)
默认情况下,集合中模型的事件已经冒泡到集合中。这样就解决了一件事,我们只需要从模型中的集合或其他模型中冒泡出事件。
我看到在层次结构中冒泡事件 as
避免这种情况的方法是命名空间事件冒泡,但这可能不适用于 trackit 。
模型的简单实现,可以冒泡任意集合或其他嵌套模型的事件:
var BubblingModel = Backbone.Model.extend({
/**
* Bubbles up any event triggered by 'object'.
* @param {Backbone.Events} obj which implement the Backbone Events.
* @param {String} key optional namespace name, default to 'nested'.
*/
addNested: function(obj, key) {
return this.listenTo(obj, 'all', function() {
arguments[0] = (key || 'nested') + ':' + arguments[0];
this.trigger.apply(this, arguments);
});
},
removeNested: function(obj) {
return this.stopListening(obj);
}
});
并使用它:
var collection = new Backbone.Collection(),
model = new BubblingModel();
model.addNested(collection, 'optional-key');
来自collection
的所有事件都会以其可选的key
或默认的nested
字符串作为前缀。由change:myAttribute
触发的collection
事件将是:
"optional-key:change:myAttribute"
使用简单测试概念证明:
// The simple implementation
var BubblingModel = Backbone.Model.extend({
/**
* Bubbles up any event triggered by 'object'.
* @param {Backbone.Events} obj which implement the Backbone Events.
* @param {String} key optional namespace name, default to 'nested'.
*/
addNested: function(obj, key) {
return this.listenTo(obj, 'all', function() {
arguments[0] = (key || 'nested') + ':' + arguments[0];
this.trigger.apply(this, arguments);
});
},
removeNested: function(obj) {
return this.stopListening(obj);
}
});
// Setting up a test with multiple nesting
var model5 = new Backbone.Model(),
model4 = new Backbone.Model(),
model3 = new BubblingModel({ model: model4 }),
col2 = new Backbone.Collection([model3]),
model2 = new BubblingModel({ col: col2 }),
col1 = new Backbone.Collection([model2]),
model1 = new BubblingModel({ col: col1 });
// Set which you want to bubble up.
model3.addNested(model4, 'model3-nested-model');
model2.addNested(col2, 'model2-nested-col')
.addNested(model5);
model1.addNested(col1, 'model1-nested-col');
// listen from any model down the chain
Backbone.listenTo(model2, 'all', function(eventName) {
console.log("model2:", eventName);
});
Backbone.listenTo(model1, 'all', function(eventName) {
console.log("model1:", eventName);
});
// trigger default or custom events
model3.set('test', 1);
model3.trigger('model3');
model4.trigger('model4');
model5.trigger('model5');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>