Knockout.js使用“with”绑定困境

时间:2013-01-04 19:51:03

标签: javascript asp.net-mvc knockout.js

我的应用程序具有以下设置(或多或少):

JS

var ObjectVM = function(data) {
    var me = this;
    me.name = ko.observable(data.name);
    //Set other properties
    ...

    me.isSelected(false);
};
var VM = function () {
    var me = this;
    me.Records = [];
    me.Selected = ko.observable(undefined);
    me.Select = function (rec) {
        if (rec.hasChanges == undefined) {
            //attach editable functionality
            ko.editable(record);
        }
        rec.isSelected(true);
        rec.beginEdit();
        if (me.Selected() != undefined) {
            if (me.Selected().hasChanges()) {
                me.Selected().rollback();
            }
            me.Selected().isSelected(false);
            me.Selected().commit();
        }
        me.Selected(rec);
        //Do some hiding/showing of form...
    };
    me.Init = function(){
       $.ajax({...,
          success: function(data){
          for(var i = 0;i< data.length;i++){
           me.Records.push(new ObjectVM(data[i]));
          }
       }
    };
};

HTML

<div>
     RECORDS DISPLAY GRID (Pretend it's a table with 5 columns and 10 rows)
</div>
<div data-bind="with: Selected">
   <form id="editRec">
     <label>Name</label>
      <input data-bind="value: name" />
   </form>
</div>

我在表行上有一个单击绑定设置,调用VMs选择功能。使用“with”绑定会在Selected()未定义时删除表单,并在Selected()具有记录时添加回来。每次发生这种情况的问题,我都会丢失附加到表单的验证,选项卡和事件绑定(非KO绑定)。应用程序运行完美,但在记录之间进行更改时会有一些性能命中,因为它必须重新添加表单,设置验证,ui配置和绑定。

有没有办法让表单保留在页面上,保留我的绑定和设置,或者每次选择的值更改时我是否会被迫处理命中?

1 个答案:

答案 0 :(得分:2)

目前,with绑定将其内容视为模板,并在with值更改时重新呈现。避免重新渲染的唯一方法是不使用with

<div>
   <form id="editRec">
     <label>Name</label>
      <input data-bind="value: Selected().name" />
   </form>
</div>

当然,如果Selected有时可能是undefined,那么这将无效,您必须寻找其他解决方案。最好的方法是使用自定义绑定来设置事件处理程序,验证,选项卡等。

<!--ko with: Selected-->
<div data-bind="setUpStuff: true">
   <form id="editRec">
     <label>Name</label>
      <input data-bind="value: name" />
   </form>
</div>
<!--/ko-->

避免某些重新呈现并且还支持undefined值的第三种方法是使用Knockout 2.2和if绑定(并避免with)。在2.2中,if绑定只会在值变为真值时重新呈现,但如果它从一个真值变为另一个真值,则不会重新呈现。

<!--ko if: Selected-->
<div data-bind="setUpStuff: true">
   <form id="editRec">
     <label>Name</label>
      <input data-bind="value: Selected().name" />
   </form>
</div>
<!--/ko-->