2012-10-19 32 views
0

我正在使用knockout.js。我創建了一個視圖模型,說testViewModel只有1可觀察到的屬性testProperty如何檢測knockout.js中除change事件以外的更改

function testViewModel() 
{ 
    var self = this; 

    self.testProperty = ko.observable("Initial"); 

} 

比我創建了一個span其中的testProperty改變值被反射和input text field,使我們可以改變testProperty值。

<span data-bind="text: testProperty"></span><br /> 
<input type="text" data-bind="value: testProperty" /> 

我創建了一個Example Fiddle。看來,當在輸入文本字段執行focusOut事件的觀察到的屬性值被更新。

現在我的問題是我們可以改變觀察到的屬性值更新事件從焦點到別的東西。我還創建了一個保存按鈕。只有在保存按鈕按下時纔有更新observable屬性值的方法。

我想創造一個用戶可以創建並保存其個人資料,並可以編輯保存profile.I正在使用相同的可觀察性的應用程序創建和編輯的形式和這些屬性是可觀察的。所以當用戶編輯它的配置文件時,用戶應該不更新 ,直到用戶按下保存按鈕。這是我的目標。請幫我解決這個問題?

回答

1

最簡單的做法是爲每個屬性設置一個影子屬性。因此,將一個文本框綁定到文本框時,只需將該值複製到其他屬性,即單擊保存時綁定到其他UI元素的屬性。

在這裏看到:http://jsbin.com/aguyud/5/edit

使用兩個模型和$ .extend從一個複製到其他更簡單的方法:

http://jsbin.com/aguyud/7/edit

更新,實際上是從頭開始的,似乎不是上班。我嘗試這樣做,而不是:

http://jsbin.com/aguyud/22/edit

其運作第一次,但複製與$ .extend模型後,似乎它被複制所有綁定了,所以它只能一次!

+0

感謝您的回覆,但我有很多屬性,所以這是一個很好的做法,使屬性數加倍(意味着創建每個屬性的副本)? –

+0

@TomRider:處理它的另一種方法是創建兩個單獨的模型。如果頁面具有不同的父DOM元素,則可以在頁面上綁定多個模型。然後,您可以將一個綁定爲可編輯,另一個綁定爲顯示。單擊保存時,只需將可編輯的值複製到顯示的一個。或者更好,但只是[克隆它](http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object)。比每個變量有兩個副本更容易一些? –

+0

@TomRider:我在答案中增加了另一個版本,通過保留兩個模型來消除複製每個屬性的複雜性。只要您可以將每個模型綁定到不同的DOM元素,它就會工作。或者,您可以將它們嵌套在單個父視圖模型中,以消除該限制。 –

4

我會建議有testProperty和testProperty_temp。綁定輸入溫度,並單擊按鈕時,設置testProperty到testProperty_temp

function testViewModel() 
{ 
    var self = this; 

    self.testProperty = ko.observable("Initial"); 
    self.testProperty_temp = ko.obserable(""); 
    self.save = function() { self.testProperty(self.testProperty_temp()); } 
} 

希望這有助於

+0

感謝您的回覆,但我有很多屬性,所以這是一個很好的做法,使屬性數加倍(意味着創建每個屬性的副本)? –

2

另一種方式,沿着什麼馬特Burland提出同樣的思路:

http://jsfiddle.net/mori57/PQxJC/

基本上,將輸入和按鈕封裝在一個表單中,並綁定表單以提交:這是通過ViewModel上的方法處理的。見我行內所提出的意見,但在這裏它是誰也不想出去的jsfiddle人:

<span data-bind="text: testProperty"></span><br /> 
<!-- wrap the input and button in a form and 
    data-bind to submit, with a reference 
    to a handler on your viewmodel --> 
<form data-bind="submit: updateProfile"> 
<!-- this must be bound to your shadow value --> 
<input type="text" data-bind="value: _tmpTestProperty" /> 
<button type="submit">save</button> 
</form>​ 

,並在你的JavaScript

function testViewModel() 
{ 
    var self = this; 

    self.testProperty = ko.observable("Initial"); 
    // Create the "shadow" property 
    // and prepopulate it with testProperty's value 
    self._tmpTestProperty = ko.observable(self.testProperty()); 

    // Create our form handler 
    self.updateProfile = function(val){ 
    // set the testProperty value to the 
    // value of the shadow property 
    self.testProperty(self._tmpTestProperty()); 
    }; 

} 

ko.applyBindings(new testViewModel());​ 

這樣,你的價值當你失去對文本輸入框的注意力時,它不會改變,但只有當你提交表單時纔會更新。

+0

感謝您的回覆,但我有很多屬性,所以這是一個很好的做法,使屬性數加倍(意味着創建每個屬性的副本)? –

+0

我會考慮,無論是使用Knockout或jQuery還是普通的舊Javascript,我需要保留多少東西來主動更新,並且只更新或綁定屬性I **必須**動態更新。我不知道Knockout的性能開銷是多少,或者領域的上限是什麼(如果有的話),但是在其他方面相同的情況下,使用Occam的Razor:最簡單的解決方案是最好的解決方案。如果您發現自己過於複雜,那麼可能是時候退一步,重新評估您正在嘗試解決的問題,並查看是否有更簡單的解決方案。 –

相關問題