rivets.js新手在这里。我想绑定到将动态更改的项(store.ActiveItem)。我尝试了以下方法,但是虽然设置了store.ActiveItem,但store.ActiveItem。(任何属性)始终是未定义的。是否存在比一个级别更深层次绑定的标准方法?
<div id="editItemDialog" data-modal="store.ActiveItem < .ActiveItem">
<a data-on-click="store:ClearActiveItem" href="#">close - works</a>
<div>
<div>
<label>name:</label><input data-value="store.ActiveItem.Name < .ActiveItem"/>
</div>
<div>
<label>price:</label><input data-value="store.ActiveItem.Price < .ActiveItem"/>
</div>
<div>
<label>description:</label><textarea data-value="store.ActiveItem.Description < .ActiveItem"></textarea>
</div>
</div>
</div>
答案 0 :(得分:23)
绑定的工作原理很大程度上取决于您使用的铆钉适配器,尽管您的模型也可以完成繁重的工作。
如果你正在使用Backbone.js,你可以看一下backbone-deep-model,它支持嵌套属性的路径语法(例如store.get('ActiveItem.Price')
),尽管它仍处于开发阶段。如果这不能满足您的需求,Backbone plugins and extensions wiki上还有其他嵌套模型类型选项。
如果这对您不起作用,您可以扩展Rivets适配器以处理路径语法。我在http://jsfiddle.net/zKHYz/2/使用以下天真适配器编写了一个关于如何执行此操作的简单示例:
rivets.configure({
adapter: {
subscribe: function(obj, keypath, callback) { /* Subscribe here */ },
unsubscribe: function(obj, keypath, callback) { /* Unsubscribe here */ },
read: function(obj, keypath) {
var index = keypath.indexOf('.');
if (index > -1) {
var pathA = keypath.slice(0, index);
var pathB = keypath.slice(index + 1);
return obj[pathA][pathB];
} else {
return obj[keypath];
}
},
publish: function(obj, keypath, value) {
var index = keypath.indexOf('.');
if (index > -1) {
var pathA = keypath.slice(0, index);
var pathB = keypath.slice(index + 1);
return obj[pathA][pathB] = value;
} else {
return obj[keypath] = value;
}
}
}
});
从版本0.3.2开始,Rivets支持iteration binding。通过创建一个返回数组的Rivets格式化程序,您可以“迭代”您的属性。请查看http://jsfiddle.net/mhsXG/3/以获取此示例:
rivets.formatters.toArray = function(value) {
return [value];
};
<div data-each-item="store.ActiveItem | toArray < store.ActiveItem"">
<label>name:</label><input data-value="item.Name < store.ActiveItem"/>
...
</div>
我不确定这里是否需要计算属性语法;你必须用你的模型测试这个,看看它有什么用。
需要绑定超过一个级别可能表明您的设计可以改进。
在您的示例中,您在商店的ItemCollection中有一个Items列表。您可以将单个Item分配给Store的ActiveItem属性,在任何地方设置事件以尝试链接事物,然后需要能够绑定到Store下ActiveItem的属性,但只要ActiveItem本身发生更改,就会更新事物等等。
更好的方法是使用每模型视图方法。在您的示例中,您尝试使用单个视图处理Store Model,ItemCollection和Item Model。相反,您可以拥有父Store视图,ItemCollection的子视图,然后根据需要生成Item视图。这样,视图更易于构建和调试,与整体模型设计的关联性较低,并且在整个应用程序中更易于重用。在此示例中,它还简化了模型设计,因为您不再需要Store上的ActiveItem属性来尝试维护状态;您只需将项目视图绑定到选定的项目模型,所有内容都将通过项目视图发布。
如果您使用Backbone.js,请查看Backbone.View作为起点;网上有很多例子,虽然我会第一个承认事情会变得有些复杂,特别是当你有嵌套视图时。我听说过有关Backbone.LayoutManager的好消息,以及它如何降低这种复杂性,但还没有机会自己使用它。
我已经修改了您最近的示例,以便在http://jsfiddle.net/EAvXT/8/使用生成的项目视图,并相应地取消了ActiveItem属性。虽然我没有从ItemCollection视图中拆分Store视图,但请注意我将它们的模型分别传递给Rivets以避免需要绑定到store.Items.models
。同样,这是一个相当天真的示例,并且在删除视图时无法处理完整的View生命周期,例如unbinding Rivets。