2012-11-01 100 views
2

我試圖逐漸將KnockoutJS灑到我現有的應用程序中。我第一次嘗試這種做法是採取一些小的現有形式,並將它們的值在模糊處推送到服務器,並通過綁定更新一些元素。來自ViewModel的綁定值

我遇到的問題是,當表單第一次顯示時,它不會通過淘汰填充。我使用表單中已有的數據渲染頁面。所以我安裝我的淘汰賽這樣的:

function DomainViewModel() { 
    this.name = ""; 
    this.description = ""; 
} 

ko.applyBindings(new DomainViewModel()); 

我有我的窗體像這樣:

<input data-bind="value: name" value="${domainInstance.name.encodeAsHTML()}"/> 
<textarea data-bind="value: description" >${domainInstance.description.encodeAsHTML()}</textarea> 

所以會顯示我的形式發生了什麼,然後淘汰賽從視圖模型應用價值的表單,它清除了服務器放在那裏的值。我明白爲什麼會發生這種情況,而這不是一個錯誤。不過,我想知道這裏是否還有其他選擇。

我知道我可以做類似如下:

function DomainViewModel() { 
    this.name = "${domainInstance.name}"; 
    this.description = "${domainInstance.name}"; 
} 

但這需要我在GSP放一些javascript的直接(我使用的Grails),而不是外部腳本文件。

回答

5

所以,你有幾種方法可以做到這一點。首先,千萬不要這樣做

function DomainViewModel() { 
    this.name = "${domainInstance.name}"; 
    this.description = "${domainInstance.name}"; 
} 

您的viewmodel已變得不可重用。如果您想使用grails來填充視圖模型,請在頁面上設置一些javascript對象,並將其傳遞到您的外部javascript文件視圖模型定義中,如下所示(請勿忘記使您的屬性變爲可疑!):

var grailsData = { 
    name : "${domainInstance.name}", 
    description : "${domainInstance.name}" 
}; 

    ... 
function DomainViewModel(data) { 
    this.name = ko.observable(data.name); 
    this.description = ko.observable(data.description); 
} 

ko.applyBindings(new DomainViewModel(grailsData); 

我會推薦這種方法,因爲稍後當您更改數據源時,您不必更改HTML。但是,還有另一種選擇。您可以創建一個綁定,從元素中收集值並使用它來設置初始可觀察值。這種結合可能是這樣的:

ko.bindingHandlers.valueWithInit= { 
    init: function(element, valueAccessor) { 
     valueAccessor()(element.value); 
    }, 
    update: function(element, valueAccessor) { 
     var value = valueAccessor(); 
     element.value = ko.utils.unwrapObservable(value); 
    } 
}; 

這裏是a fiddle揭示了動作

+0

這種方法如何簡單。 :) 謝謝。 – Gregg