【问题标题】:jQuery templates plugin: how to create two-way binding?jQuery 模板插件:如何创建双向绑定?
【发布时间】:2011-07-03 01:56:09
【问题描述】:

我开始使用 jQuery 模板插件(微软创建的那个),但现在我遇到了这个问题:模板用于绑定到对象数组的一堆表单;当我在其中一个表单上更改某些内容时,我希望绑定对象更新,但我不知道如何自动化。

这是一个简单的例子(现实生活中的模板和对象要复杂得多):

<!-- Template -->
<script type="text/html" id="tmplTest">
    <input type="text" value="${textvalue}"/>
</script>

<!-- object to bind -->
<script type="text/javascript">
    var obj = [{textvalue : "text1"},{textvalue : "text2"}]

    jQuery("#tmplTest").tmpl(obj)
</script>

这将填充两个文本框,每个文本框都绑定到相应对象的值。现在,如果我更改其中一个文本框中的值,我需要更新相应数据对象的值。知道怎么做吗?

【问题讨论】:

  • 看看数据链接插件:github.com/jquery/jquery-datalink
  • 我知道这个插件,但问题是 - 我不能使用它,因为我没有模板生成的单个 html 元素
  • 你的 json 不正确:{member: "value"} ;)
  • 看看 knockoutjs (observableArray),重复项是任何数据绑定库都应该解决的常见任务,我很惊讶它还没有在 datalink 中完成;)

标签: javascript jquery data-binding jquery-templates two-way


【解决方案1】:

您可以编写自己的数据链接。 注意:我需要索引来完成这项工作,所以我将您的数据添加到一个数组中,并在模板中放置了一个 each。如果有人知道如何在不使用 each 的情况下获取索引,请添加:) jsfiddle link

<script type="text/html" id="tmplTest">
    {{each inputs}}
    <input type="text" class="datalink" data-key="textvalue" data-index="${$index}" value="${$value.textvalue}"/>
    {{/each}}
</script>
<div id="output"></div>


$.extend(window, {
    data:[
        {inputs: [{textvalue:"text1"},{textvalue:"text2"}]}
    ]
});

$('#output').append($("#tmplTest").tmpl(window.data));

$('#output .datalink').live('change', function(){ // update object on change
    var $this = $(this),
        d = $this.data();
    window.data[0].inputs[d.index*1][d.key] = $this.val();
    console.log(window.data[0].inputs);
});

【讨论】:

  • 不,我说的是当用户更新 html 字段时更新模板数据对象
  • 玩弄 jsfiddle,更新文本框中的值似乎不会更新 JSON 数组中的值。似乎从未真正触发过实时“更改”。
  • @Serge - 控制台日志具有欺骗性。在每次更改之间清除控制台,您将看到对象更改。
【解决方案2】:

jQuery 模板实际上并没有实现双向数据绑定,但是另一个 Microsoft 开发的 jQuery 插件可以实现。 这个Scott Guthrie post 实际上涵盖了 tmpl 插件和 Data Linking 插件。向下滚动到“支持客户端数据链接”,Scott 详细介绍了数据链接插件的工作原理。

但是,对于双向数据绑定,我发现knockoutjs 扩展更好更简洁。 declarative 语法保持标记干净,custom data binding overrides 允许大量应用程序。最后,mapping plugin 非常适合将来自服务器的 JSON 处理为绑定。最后,knockoutjs 也有bindings based on tmpl plugin

祝你好运。

编辑:更新代码示例

需要脚本:

<script src="/Scripts/jquery-1.5.0.min.js" type="text/javascript"></script>    
<script src="/Scripts/jquery.tmpl.js" type="text/javascript"></script> 
<script src="/Scripts/knockout.js" type="text/javascript"></script>      
<script src="/Scripts/knockout.mapping.js" type="text/javascript"></script>    

然后这里是肉和土豆

<!-- div for loading the template -->
<div data-bind='template: { name: "tmplTest", foreach: viewModel.list }'>    
</div>

<!-- your template -->
<script type='text/html' id='tmplTest'>
    <div>        
        <span data-bind='text: textvalue, uniqueName: true'></span>
        <input data-bind='value: textvalue, uniqueName: true, valueUpdate:"afterkeydown"'/>
    </div>
</script>

<script type='text/javascript'>
       var viewModel = ko.mapping.fromJS(
        {            
            list:[  { textvalue: "text1" },
                    { textvalue: "text2"}   ]
                }); 

        $(function() {
            ko.applyBindings(viewModel);
        });
 </script>

【讨论】:

  • 我已经阅读了 ScottGu 的文章(这就是我最初是如何发现模板插件的),但他在文章中描述的内容和插件的实际实现是两件不同的事情。他们没有将双向绑定集成到模板引擎中(添加 {link field}) - 我想它只是作为提案保留......
  • 你真的应该看看淘汰赛的东西。 MVVM 似乎是使用基于 AJAX 的 HTML 应用程序的方式。
  • Serge,你能用我的具体例子告诉我如何使用敲除进行双向绑定吗?
  • 据我所知,knockout 也提供了自己的模板引擎,对吧?那么我可以用它来替换 MS 的 tmpl 插件吗?
  • @Serge:非常感谢,这真的很有帮助!
猜你喜欢
  • 2019-10-26
  • 2021-08-10
  • 1970-01-01
  • 2016-12-02
  • 2016-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-20
相关资源
最近更新 更多