微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 如何使用rivets.js绑定比一个级别更深

rivets.js newbie这里.我想绑定到一个将动态变化的项目(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>

解决方法

绑定工作的方式在很大程度上取决于您所使用的铆钉适配器,尽管您的型号也可以提升重量.

选项1:智能模型

如果您使用Backbone.js,您可以查看backbone-deep-model,它支持嵌套属性的路径语法(例如.store.get(‘ActiveItem.Price’)),尽管它仍在开发中.如果这不符合您的需求,Backbone plugins and extensions wiki上还有其他嵌套的模型类型选项.

选项2:智能适配器

如果这不适合您,则可以扩展您的铆钉适配器来处理路径语法.我已经在一个简单的例子,如何在http://jsfiddle.net/zKHYz/2/与以下naive适配器:

rivets.configure({
    adapter: {
        subscribe: function(obj,keypath,callback) { /* Subscribe here */ },unsubscribe: function(obj,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,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;
            }
        }
    }
});

选项3:肮脏的黑客

从版本0.3.2开始,铆钉支持iteration binding.通过创建一个返回数组的铆钉格式化程序,可以“迭代”您的属性.看看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>

我不知道在这里是否需要计算的属性语法?你必须用你的模型来测试这个,看看有什么作用.

选项4:不要绑定在一个级别以上(推荐)

绑定深度超过一个级别的需要可能表明您的设计可以改进.

在您的示例中,您有一个商店的ItemCollection中的Items列表.您将分配一个单独的项目到商店的ActiveItem属性,设置各处的事件以一起尝试链接的东西,然后需要能够绑定到存储下的ActiveItem的属性,但随着ActiveItem本身更改等等.

一个更好的方法是使用每模型视图.在您的示例中,您正在尝试使用单个视图处理商店模型,ItemCollection和项目模型.相反,您可以有一个父商店视图,ItemCollection的子视图,然后根据需要生成Item视图.这样,视图更容易构建和调试,与您的整体模型设计紧密耦合,并在整个应用程序中更容易重用.在这个例子中,它也简化了您的Model设计,因为您不再需要Store上的ActiveItem属性来尝试维护状态;您只需将项目视图绑定到所选项目模型,并且所有内容都将随物品视图一起发布.

如果您使用Backbone.js,请查看Backbone.View作为起点;网上有很多例子,尽管我将首先承认事情会变得有些复杂,特别是当你有嵌套视图时.听到有关Backbone.LayoutManager的好消息,以及如何降低这种复杂性,但还没有机会自己使用它.

修改了你最近的例子,在http://jsfiddle.net/EAvXT/8/使用生成的Item视图,并相应地删除了ActiveItem属性.虽然我没有从ItemCollection视图拆分商店视图,但请注意,我将其模型分别导入铆钉,以避免需要绑定到store.Items.models.再次,这是一个非常幼稚的例子,并且不处理完整的View生命周期,例如在删除视图时的unbinding Rivets.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐