ko.computed()可在read/write方法加入邏輯,概念上就跟C#屬性可定義get及set一樣,能實現自訂屬性讀寫規則,如下面的C#範例,有機會在set UserName時實施不合法字元檢核:

private string userName = string.Empty;
public string UserName
{
    get
    {
        return userName;
    }
    set
    {
        //檢查是否包含不合法字元
        if (containsInvalidChars(value))
            throw new ArgumentException("包含不合法字元(,/\+!): " + value);
        userName = value;
    }
}

相同概念也可在Knockout computed實現。例如我們在ViewModel定義一固只應存放數字的observable(相當於C#例子中的private string userName),另外再定義一個computed開放外界間接存取該observable(相當於C#例子中的public string UserName),如此便有機會在write函數檢查所設定的新值是否為有效數字,甚至設定數值是否有效的旗標,再以visible繫結切換是否要顯示"非有效數字"提示文字。如以下程式範例:

<!DOCTYPE html>
 
<html>
<head>
    <title>Lab 17 - 使用ko.computed實現資料檢核</title>
    <script src="../Scripts/jquery-1.7.2.js"></script>
    <script src="../Scripts/knockout-2.1.0.debug.js"></script>
    <script>
        function MyViewModel() {
            var self = this;
            //實際用以儲存數值的observable
            self.acceptedNumericValue = ko.observable(123);
            //標示前次寫入資料是否有效的旗標
            self.lastInputWasValid = ko.observable(true);
 
            //用computed模擬只接受數字的屬性
            self.attemptedValue = ko.computed({
                //讀取時直接由obervable傳回內容
                read: self.acceptedNumericValue,
                //寫入時進行檢核
                write: function (value) {
                    //寫入值若不是數字, 不更新至observable, 
                    //並將有效旗標設為false;
                    if (isNaN(value))
                        self.lastInputWasValid(false);
                    else {
                        //寫入值有效,旗標設true,並將值寫入observable
                        self.lastInputWasValid(true);
                        self.acceptedNumericValue(value);
                    }
                }
            });
        }
 
        $(function () {
            ko.applyBindings(new MyViewModel());
        });
    </script>
    <style>
        body, input
        {
            font-size: 9pt;
        }
    </style>
</head>
<body>
    <p>
        請輸入數字:
        <input data-bind="value: attemptedValue" />
        ViewModel儲存值=<span data-bind="text: acceptedNumericValue"></span>
    </p>
    <div data-bind="visible: !lastInputWasValid()" style="color: red">非有效數字!</div>
</body>
</html>

在這個網頁中,當在TextBox中輸入非數字,ViewModel實際存放數值的acceptedNumericValue observable將不會被改變,而lastInputWasValid則被設為false,"非有效數字!"的<div>文字則會因visible繫結出現在網頁上,達到簡單的輸入檢核效果。線上展示

在實務上,多半會用現成檢核套件,不太會採用純手工打造。而目前江湖上普受歡迎的jQuery Validation,也已有現成的整合套件(Knockout-Validation),可透過ko.observable().extend({ required: true })輕鬆為欄位加上檢核條件,之後便能呼叫ViewModel.isValid()取得檢核結果,十分方便。

俗話說: "西瓜偎大邊、處處有資源",Knockout-Kendo, Knockout-Validation足為Knockout.js正火紅的見證。

[KO系列]

http://www.darkthread.net/kolab/labs/default.aspx?m=post

Comments

Be the first to post a comment

Post a comment