2014-08-27 68 views
0

我的理解是,我有一個綁定到koObservableArray中某個特定屬性的HTML元素。由於結構的設置,它不受自己的koObservable約束。如何強制對特定HTML元素進行淘汰更新?

<input data-bind="value: A" id="x" /> 

當提交表單時,會調用一個方法,將knockout視圖模型序列化爲JSON。

這工作正常,但現在我在窗體上添加一些輸入消毒。

function sanitize(){ 
    //compute sanitized value 
    document.getElementById("x").value = sanitized_value; 
} 

現在,顯然這並不會更新挖空視圖模型。我的問題是這樣的:給定一個特定的html元素(綁定到koObservableArray中的一個屬性),我如何強制更新koObservableArray中的屬性?

理想情況下,我需要能夠做到這一點,而無需更改任何我的淘汰賽代碼。真的,我希望能夠做的就是在JavaScript中模擬導致淘汰賽視圖模型更新的任何內容。我已經瞭解到它在模糊上更新,但呼籲:

document.getElementById("x").blur(); 

未導致視圖模型更新。

+0

爲什麼不分配值向視圖模型呢? – pollirrata 2014-08-27 22:40:14

回答

2

不是一個自作聰明,但你就錯了:)如果你使用的淘汰賽,你必須在任何時候視圖模型進行操作。邏輯,消毒等不應直接觸及DOM。想想你希望你的視圖模型綁定到不同的模板的情況。保持邏輯分離是淘汰賽的重點。

現在,這並不能解決你的問題,但如果我說服你,這將會:做你說的話,你需要一個可觀察的可觀察數組。所以,當你讓你觀察到的陣列,推動觀測到它,然後改變他們:

var viewModel = { 
    mainArray: ko.observableArray() 
}; 

// I understand you've got some probably complex mapping logic, let's say you get your array from the server, and then assign it like this: 
viewModel.mainArray(arrayFromServer); 

// In that case, do this: 
ko.utils.arrayForEach(arrayFromServer, function(item) { 
    item.A = ko.observable(item.A); 
}); 
viewModel.mainArray(arrayFromServer); 

// and now if you're worried about the trip back to the server: 
var jsonStringForServer = viewModel.toJSON(); 
var plainJSObjectForServer = viewModel.toJS(); 
+2

謝謝你幫助我說服我的老闆,我們需要重做淘汰賽:) – user1646600 2014-08-29 19:34:29

0

我偶爾碰到這種情況,你需要改變事件!

下面是它的演示:http://jsfiddle.net/sifriday/q0yndje2/

演示代碼:

<input id="x" data-bind="value: a"/> 
// Create a view-model 
vm = { 
    A: ko.observable("a") 
} 

// Apply bindings; the input should now show 'a' 
ko.applyBindings(vm); 

// Change the value of the input outside of KO 
document.getElementById("x").value = "b"; 

// Trigger change, to update the VM 
var el = document.getElementById("x"); 
var evt = document.createEvent("HTMLEvents"); 
evt.initEvent("change", false, true); 
el.dispatchEvent(evt); 

// Echo the value of the vm.A to the console; it should be 'b' 
console.log(vm.A()); 

,或者如果您有jQuery的,當然,你可以更輕鬆地完成的情況下,與

$("#x").trigger("change") 
0

獲取所選元素的上下文。從上下文中,您可以訪問底層視圖模型,因此可以直接更改邊界值。不要混淆像這樣的觀點,這就是視圖模型的作用。

<input id="x" data-bind="value: a"/> 
var ele = document.getElementById('x'); 
var context = ko.contextFor(ele); 
var vm = context.$root; 
vm.a(value); 

fiddle

0

就個人而言,我不會對jQuery的瘦這樣的事情更多的比你絕對要。你越是擺脫這種淘汰方式,越是冒着將視圖與模型緊密耦合的風險(從而降低了可重用性)。這變得越來越明顯,您的模型知道更多關於視圖內的DOM元素。它在模型所期望的視角之間建立了緊密的耦合,而實際上,它不應該以需要知道的方式進行設計。

您可以輕鬆地將提交綁定放置到表單中,然後在模型內部清理數據,並且它將更加清潔。這裏有一個例子:

<form data-bind="submit: ValidateSubmit"> 
    <input data-bind="value: someField" /> 
</form> 

var myModel = { 
    someField: ko.observable(), 
    ValidateSubmit: function() { 

     //sanitize fields within model here 
     //... 
     //... 
     return true; //ensures submit occurs 
    } 
};