KnockOut JS 學習中遇到的幾個問題

最近,在項目中需要改之前同事的代碼,發現他用了KnockOut,Knockout是一個輕量級的UI類庫,通過應用MVVM模式使JavaScript前端UI簡單化(如果是正在開發的項目,建議不要使用,技術已經很老了,網上資料少,語法比較複雜,但是如果你想兼容低版本的IE瀏覽器,這是一個比較好的選擇吧。。。)

KnockOut在理解上就和之前的JS控件有不少不同的地方

1)如果你要對模型中的某個屬性和視圖層進行綁定,必須要使用ko.observable()(或者ko.observableArray()監控數組)來申明一下,然後再視圖層通過data-bind來進行綁定。如果你這樣做了,你會發現KO會把你自己的屬性全都變成函數來進行調用了。例子如下:

<div data-bind="visible: shouldShowMessage">
    You will see this message only when "shouldShowMessage" holds a true value.
</div>

<script type="text/javascript">
    var viewModel = {
        shouldShowMessage: ko.observable(true) // Message initially visible
    };
    viewModel.shouldShowMessage(false); // ... now it's hidden
    viewModel.shouldShowMessage(true); // ... now it's visible again
</script>
在你的JS代碼中當你使用viewModel的shouldShowMessage屬性時,你會發現viewModel.shouldShowMessage訪問不到改屬性,因爲它已經變成了一個函數了,你需要使用viewModel.shouldShowMessage()來進行訪問,如果需要賦值的話,通過viewModel.shouldShowMessage(true); 來賦值,有點類似jQuery的val函數的使用。

2)如果你監控的是對象,在視圖層是需要with來進行綁定的,如下面的例子,而且子屬性必須在父屬性的標籤內部。

<h1 data-bind="text: city"> </h1>
<p data-bind="with: coords">
    Latitude: <span data-bind="text: latitude"> </span>,
    Longitude: <span data-bind="text: longitude"> </span>
</p>
 
<script type="text/javascript">
    ko.applyBindings({
        city: "London",
        coords: {
            latitude:  51.5001524,
            longitude: -0.1262362
        }
    });
</script>

3)使用subscribe回調函數,每次視圖改變時,都會觸發改函數;如果有需要計算的屬性,可以使用ko.computed。

<pre name="code" class="javascript">var ViewModel = function(first, last) {
    this.firstName = ko.observable(first);
    this.lastName = ko.observable(last);
 	this.firstName.subscribe(function(newValue){
        console.log('firstName has changed '+ newValue);
    });
    this.fullName = ko.computed(function() {
        console.log('firstName or lastName has changed '+ this.firstName() + " " + this.lastName());
        return this.firstName() + " " + this.lastName();
    }, this);
};

<div class='liveExample'>   
    <p>First name: <input data-bind='value: firstName' /></p> 
    <p>Last name: <input data-bind='value: lastName' /></p> 
    <h2>Hello, <span data-bind='text: fullName'> </span>!</h2>  
</div>



4)關於監控數組。在API中有這麼一段話

Key point: An observableArray tracks which objects are in the array, not the state of those objects

Simply putting an object into an observableArray doesn’t make all of that object’s properties themselves observable. Of course, you can make those properties observable if you wish, but that’s an independent choice. An observableArray just tracks which objects it holds, and notifies listeners when objects are added or removed.

這段話的意思是,對數組的監控只監控數組本身的屬性,而不能監控數組中的每個元素的狀態。數組本身的屬性是指比如數組的長度,數組增加了或者移除了元素等等。如下面的例子,如果array數組增加了一個元素,或者減少了一個元素,數組的狀態會改變,但是如果bob的id改變了,ko是不會進行監控。但是如果想要監控這種變化的話,就需要對數組裏的對象中的每個屬性再進行監控,如下段代碼所示,即進行深度監控。

var ViewModel = function() {
    this.array = ko.observableArray([{
        name : 'join',
        id : '001'
    },{
        name : 'bob',
        id : '002'
    }
    ]);
};
 
ko.applyBindings(new ViewModel()); // This makes Knockout get to work

var ViewModel = function() {
    this.array = ko.observableArray([{
        name : ko.observable('join'),
        id : ko.observable('001')
    }
    ]);
};
 
ko.applyBindings(new ViewModel()); // This makes Knockout get to work

基本上我所遇到的問題也就這些,以上有些例子使用的是KO官網的例子http://knockoutjs.com/examples/
API http://knockoutjs.com/documentation/introduction.html
我只是在別人代碼的基礎上進行修改,並沒有深入的瞭解KO,如果所寫的有問題,還請各位大神指教。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章