2011-10-10 70 views
1

在下面的代码中,想法是如果你填入'test',这被认为是无效的,并且不应该把值写入observable。我遇到的问题是我的自定义绑定以某种方式重置了observable的值。Knockout.js:自定义绑定重设值

下面的代码的工作版本:http://jsfiddle.net/6hcpM/1/

var underlying = ko.observable('foo'); 
var errors = ko.observableArray() 
var isValid = ko.dependentObservable(function(){ 
    return errors().length === 0 
}); 

var vm = { 
    name : ko.dependentObservable({ 
     read : underlying, 
     write : function(value){ 
      errors([]); 

      if(value==='test'){ 
      errors([ 'Cant be test matey' ]); 
      }; 

      if(isValid()){ 
       underlying(value); 
      }; 
     } 
    }) 
}; 

vm.name.isValid = isValid; 

ko.bindingHandlers.validateCss = { 
    update: function(element, valueAccessor) { 
     observable = valueAccessor(); 
     observable.isValid(); //this somehow causes the problem 
    } 
}; 

ko.applyBindings(vm); 

回答

2

validateCss结合创建依赖于vm.name.isValid。当您向该字段写入“测试”时,将更新errors,这会导致isValid更新,这会触发输入的data-bind属性中的所有绑定进行重新评估。因此,value绑定会被再次评估并将当前值替换为name(存储在underlying中)的值。

因此,基本上value绑定正在根据isValid更改再次运行。

有几种方法可以处理它。您可以每次更新underlying,如有必要,可以在其他地方存储一个干净的值,只有在有效时才更新。

您也可以将您的自定义绑定到不同的元素上。例如,你可以将你的input包装在一个span或div中,并将绑定放在它上面。我假设你希望validateCss绑定在值无效时分配一个CSS类。

+0

将validateCss放在不同的元素上听起来像是一个很好的解决方案。 – Pickels