【问题标题】:How to use custom bindings?如何使用自定义绑定?
【发布时间】:2011-06-01 05:34:40
【问题描述】:

我有一个大型 viewModel,我想将状态(“已读”/“未读”)的更新发布到服务器而不发布整个模型。

我所做的是像这样创建一个自定义绑定:

ko.bindingHandlers.statusUpdater = {
    update: function(element, valueAccessor) {
        console.log(element);
    }
};

在模板中:

<div data-bind='template: { name: "contactsListTemplate", data: viewModel.conversations.conversationlist }'> </div>

<script type="text/html" id="contactsListTemplate">
 <table>
  <tbody>
   {{each(i, conversation) $data}}
    <tr>
     <td>
      <input type="checkbox" data-bind="checked: read, statusUpdater: conversation_id" />
     </td>
    </tr>
   {{/each}}
  </tbody>
 </table>
</script>

对于自定义绑定,我只对更新感兴趣,我认为可以使用 KnockoutJS 检测更新,并确定更新了哪个项目,以便我可以获取该项目 ID 和新统计信息,然后将其发布到服务器。

发生的事情是 customBinding 是 console.logging 对单个复选框修改的每个复选框。这意味着我更改了一个复选框,所有 3 个复选框都通过ko.bindingHandlers.statusUpdater 登录到控制台。

我曾考虑在数据绑定中添加点击事件,但这似乎不如自定义绑定干净。也许我试图用自定义绑定做的不是它们的用途?

想法?

【问题讨论】:

    标签: jquery knockout.js


    【解决方案1】:

    这样做的原因是因为每次更新模型值时都会调用 update 方法,并且在调用 init 方法之后的开始时调用。

    update绑定方法是让你在viewmodel改变时设置绑定的dom元素的状态。

    如果您想对更改做出反应并更新 viewModel,您将需要实现 init 方法并附加一个事件(单击、更改等),然后您可以在此处理程序中将状态更新发送到您的 viewmodel。

    ko.bindingHandlers.statusUpdater = {
        'init': function (element, valueAccessor, allBindingsAccessor) {
    
            var updateHandler = function() {            
                var valueToWrite;
                if (element.type == "checkbox") {
                    valueToWrite = element.checked;
                } else if ((element.type == "radio") && (element.checked)) {
                    valueToWrite = element.value;
                } else {
                    return; // "checked" binding only responds to checkboxes and selected radio buttons
                }
    
                var modelValue = valueAccessor();
    
                if (ko.isWriteableObservable(modelValue)) {             
                    if (modelValue() !== valueToWrite) { // Suppress repeated events when there's nothing new to notify (some browsers raise them)
                        $.ajax({
                          url: 'someurl',
                          success: function(data) {
                                alert('status update');
                          }
                        });
                        modelValue(valueToWrite);
                    }
                } else {
                    var allBindings = allBindingsAccessor();
                    if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['checked']) {
                        allBindings['_ko_property_writers']['checked'](valueToWrite);
                    }
                }
            };
    
            $(element).click(updateHandler).change(updateHandler);
        },
        'update': function (element, valueAccessor) {
            ko.bindingHandlers.checked(element, valueAccessor);
        }
    };
    

    我发现最好的学习方法是查看 git 上的 KO 调试版本。您想要实现的基本上是带有 ajax 调用的修改后的检查绑定。

    我还没有测试过上述内容,但它应该可以帮助您入门。

    干杯,

    伊恩

    【讨论】:

    • 谢谢你,但是 data-bind="" 里面的视图会是什么样子,我似乎还无法在这个 knockoutjs 的东西上连接点。谢谢
    猜你喜欢
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2019-11-21
    • 2023-03-12
    相关资源
    最近更新 更多