綁定語(yǔ)法(3)

2018-02-24 15:25 更新

12 ? value 綁定

目的

value綁定是關(guān)聯(lián)DOM元素的值到view model的屬性上。主要是用在表單控件,和上。

當(dāng)用戶編輯表單控件的時(shí)候, view model對(duì)應(yīng)的屬性值會(huì)自動(dòng)更新。同樣,當(dāng)你更新view model屬性的時(shí)候,相對(duì)應(yīng)的元素值在頁(yè)面上也會(huì)自動(dòng)更新。

注:如果你在checkbox或者radio button上使用checked綁定來(lái)讀取或者寫入元素的 checked狀態(tài),而不是value 值的綁定。

例子

<p>Login name: <input data-bind="value: userName"/></p>
<p>Password: <input type="password" data-bind="value: userPassword"/></p>

<script type="text/javascript">
    var viewModel = {
        userName: ko.observable(""),        // Initially blank
        userPassword: ko.observable("abc"), // Prepopulate
    };
</script>

參數(shù)

????主參數(shù)

??? KO設(shè)置此參數(shù)為元素的value值。之前的值將被覆蓋。

??? 如果參數(shù)是監(jiān)控屬性observable的,那元素的value值將根據(jù)參數(shù)值的變化而更新,如果不是,那元素的value值將只設(shè)置一次并且以后不在更新。

??? 如果你提供的參數(shù)不是一個(gè)數(shù)字或者字符串(而是對(duì)象或者數(shù)組)的話,那顯示的value值就是yourParameter.toString() 的內(nèi)容(通常沒(méi)用,所以最好都設(shè)置為數(shù)字或者字符串)。

??? 不管什么時(shí)候,只要你更新了元素的值,那 KO都會(huì)將view model對(duì)應(yīng)的屬性值自動(dòng)更新。默認(rèn)情況下當(dāng)用戶離開焦點(diǎn)(例如onchange事件)的時(shí)候,KO才更新這個(gè)值,但是你可以通過(guò)第2個(gè)參數(shù)valueUpdate來(lái)特別指定改變值的時(shí)機(jī)。

????其它參數(shù)

????????valueUpdate

??????? 如果你使用valueUpdate參數(shù),那就是意味著KO將使用自定義的事件而不是默認(rèn)的離開焦點(diǎn)事件。下面是一些最常用的選項(xiàng):

??????????? “change”(默認(rèn)值) - 當(dāng)失去焦點(diǎn)的時(shí)候更新view model的值,或者是 元素被選擇的時(shí)候。

??????????? “keyup” – 當(dāng)用戶敲完一個(gè)字符以后立即更新view model。

??????????? “keypress” – 當(dāng)用戶正在敲一個(gè)字符但沒(méi)有釋放鍵盤的時(shí)候就立即更新view model。不像 keyup,這個(gè)更新和keydown是一樣的。

??????????? “afterkeydown” – 當(dāng)用戶開始輸入字符的時(shí)候就更新view model。主要是捕獲瀏覽器的keydown事件或異步handle事件。

??????? 上述這些選項(xiàng),如果你想讓你的view model進(jìn)行實(shí)時(shí)更新,使用“afterkeydown”是最好的選擇。

例子:

<p>Your value: <input data-bind="value: someValue, valueUpdate: 'afterkeydown'"/></p>
<p>You have typed: <span data-bind="text: someValue"></span></p> <!-- updates in real-time --> 

<script type="text/javascript">
    var viewModel = {
        someValue: ko.observable("edit me")
    };
</script>

注1:綁定下拉菜單drop-down list(例如SELECT)

Knockout對(duì)下拉菜單drop-down list綁定有一個(gè)特殊的支持,那就是在讀取和寫入綁定的時(shí)候,這個(gè)值可以是任意JavaScript對(duì)象,而不必非得是字符串。在你讓你用戶選擇一組model對(duì)象的時(shí)候非常有用。具體例子,參考o(jì)ptions綁定。

類似,如果你想創(chuàng)建一個(gè)multi-select list,參考selectedOptions綁定。

注2:更新observable和non-observable屬性值

如果你用value綁定將你的表單元素和你的observable屬性關(guān)聯(lián)起來(lái),KO設(shè)置的2-way的雙向綁定,任何一方改變都會(huì)更新另外一方的值。

但是,如果你的元素綁定的是一個(gè)non-observable屬性(例如是一個(gè)原始的字符串或者JavaScript表達(dá)式) ,KO會(huì)這樣執(zhí)行:

  • 如果你綁定的non-observable屬性是簡(jiǎn)單對(duì)象,例如一個(gè)常見(jiàn)的屬性值,KO會(huì)設(shè)置這個(gè)值為form表單元素的初始值,如果你改變form表單元素的值,KO會(huì)將值重新寫回到view mode的這個(gè)屬性。但當(dāng)這個(gè)屬性自己改變的時(shí)候,元素卻不會(huì)再變化了(因?yàn)椴皇莖bservable的),所以它僅僅是1-way綁定。
  • 如果你綁定的non-observable屬性是復(fù)雜對(duì)象,例如復(fù)雜的JavaScript 表達(dá)式或者子屬性,KO也會(huì)設(shè)置這個(gè)值為form表單元素的初始值,但是改變form表單元素的值的時(shí)候,KO不會(huì)再寫會(huì)view model屬性,這種情況叫one-time-only value setter,不是真正的綁定。

例子:

<p>First value: <input data-bind="value: firstValue"/></p>          <!-- two-way binding -->
<p>Second value: <input data-bind="value: secondValue"/></p>        <!-- one-way binding -->
<p>Third value: <input data-bind="value: secondValue.length"/></p>  <!-- no binding --> 

<script type="text/javascript">
    var viewModel = {
        firstValue: ko.observable("hello"), // Observable
        secondValue: "hello, again"http:// Not observable
    };
    ko.applyBindings(viewModel);
</script>

依賴性

除KO核心類庫(kù)外,無(wú)依賴。

13 ? checked 綁定

目的

checked綁定是關(guān)聯(lián)到checkable的form表單控件到view model上 - 例如checkbox()或者radio button() 。當(dāng)用戶check關(guān)聯(lián)的form表單控件的時(shí)候,view model對(duì)應(yīng)的值也會(huì)自動(dòng)更新,相反,如果view model的值改變了,那控件元素的check/uncheck狀態(tài)也會(huì)跟著改變。

注:對(duì)text box,drop-down list和所有non-checkable的form表單控件,用value綁定來(lái)讀取和寫入是該元素的值,而不是checked綁定。

例子

<p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam"/></p> 

<script type="text/javascript">
    var viewModel = {
        wantsSpam: ko.observable(true) // Initially checked
    };

     // ... then later ...
    viewModel.wantsSpam(false); // The checkbox becomes unchecked
</script>

Checkbox關(guān)聯(lián)到數(shù)組

<p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam"/></p>
<div data-bind="visible: wantsSpam">
    Preferred flavors of spam:
    <div><input type="checkbox" value="cherry" data-bind="checked: spamFlavors"/> Cherry</div>
    <div><input type="checkbox" value="almond" data-bind="checked: spamFlavors"/> Almond</div>
    <div><input type="checkbox" value="msg" data-bind="checked: spamFlavors"/> Monosodium Glutamate</div>
</div>

<script type="text/javascript">

    var viewModel = {
        wantsSpam: ko.observable(true),
        spamFlavors: ko.observableArray(["cherry", "almond"]) // Initially checks the Cherry and Almond checkboxes
    };

    // ... then later ...
    viewModel.spamFlavors.push("msg"); // Now additionally checks the Monosodium Glutamate checkbox
</script>

添加radio button

<p>Send me spam: <input type="checkbox" data-bind="checked: wantsSpam"/></p>

<div data-bind="visible: wantsSpam">
    Preferred flavor of spam:
    <div><input type="radio" name="flavorGroup" value="cherry" data-bind="checked: spamFlavor"/> Cherry</div>
    <div><input type="radio" name="flavorGroup" value="almond" data-bind="checked: spamFlavor"/> Almond</div>
    <div><input type="radio" name="flavorGroup" value="msg" data-bind="checked: spamFlavor"/> Monosodium Glutamate</div>
</div>

<script type="text/javascript">

    var viewModel = {
        wantsSpam: ko.observable(true),
        spamFlavor: ko.observable("almond") // Initially selects only the Almond radio button
    };

     // ... then later ...
    viewModel.spamFlavor("msg"); // Now only Monosodium Glutamate is checked
</script>

參數(shù)

????主參數(shù)

??? KO會(huì)設(shè)置元素的checked狀態(tài)匹配到你的參數(shù)上,之前的值將被覆蓋。對(duì)參數(shù)的解析取決于你元素的類型:

??????? 對(duì)于checkbox,當(dāng)參數(shù)為true的時(shí)候,KO會(huì)設(shè)置元素的狀態(tài)為checked,反正設(shè)置為unchecked。如果你傳的參數(shù)不是布爾值,那KO將會(huì)解析成布爾值。也就是說(shuō)非0值和非null對(duì)象,非空字符串將被解析成true,其它值都被解析成false。

??????? 當(dāng)用戶check或者uncheck這個(gè)checkbox的時(shí)候,KO會(huì)將view model的屬性值相應(yīng)地設(shè)置為true或者false。

??????? 一個(gè)特殊情況是參數(shù)是一個(gè)數(shù)組,如果元素的值存在于數(shù)組,KO就會(huì)將元素設(shè)置為checked,如果數(shù)組里不存在,就設(shè)置為unchecked。如果用戶對(duì)checkbox進(jìn)行check或uncheck,KO就會(huì)將元素的值添加數(shù)組或者從數(shù)組里刪除。

??????? 對(duì)于radio buttons,KO只有當(dāng)參數(shù)值等于radio button value屬性值的時(shí)候才設(shè)置元素為checked狀態(tài)。所以參數(shù)應(yīng)是字符串。在上面的例子里只有當(dāng)view model 的spamFlavor 屬性等于“almond”的時(shí)候,該radio button才會(huì)設(shè)置為checked。

??????? 當(dāng)用戶將一個(gè)radio button選擇上的時(shí)候 is selected,KO會(huì)將該元素的value屬性值更新到view model屬性里。上面的例子,當(dāng)點(diǎn)擊value= “cherry”的選項(xiàng)上, viewModel.spamFlavor的值將被設(shè)置為“cherry”。

??????? 當(dāng)然,最有用的是設(shè)置一組radio button元素對(duì)應(yīng)到一個(gè)單個(gè)的view model 屬性。確保一次只能選擇一個(gè)radio button需要將他們的name屬性名都設(shè)置成一樣的值(例如上個(gè)例子的flavorGroup值)。這樣的話,一次就只能選擇一個(gè)了。

??? 如果參數(shù)是監(jiān)控屬性observable的,那元素的checked狀態(tài)將根據(jù)參數(shù)值的變化而更新,如果不是,那元素的value值將只設(shè)置一次并且以后不在更新。

???其它參數(shù)

??? 無(wú)

依賴性

除KO核心類庫(kù)外,無(wú)依賴。

14 ? options 綁定

目的

options綁定控制什么樣的options在drop-down列表里(例如:)或者 multi-select 列表里 (例如:)顯示。此綁定不能用于之外的元素。關(guān)聯(lián)的數(shù)據(jù)應(yīng)是數(shù)組(或者是observable數(shù)組),會(huì)遍歷顯示數(shù)組里的所有的項(xiàng)。

注:對(duì)于multi-select列表,設(shè)置或者獲取選擇的多項(xiàng)需要使用selectedOptions綁定。對(duì)于single-select列表,你也可以使用value綁定讀取或者設(shè)置元素的selected項(xiàng)。

例1:Drop-down list

<p>Destination country: <select data-bind="options: availableCountries"></select></p>

<script type="text/javascript">
    var viewModel = {
        availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) // These are the initial options
    };

    // ... then later ...
    viewModel.availableCountries.push('China'); // Adds another option
</script>

例2:Multi-select list

<p>Choose some countries you'd like to visit: <select data-bind="options: availableCountries" size="5" multiple="true"></select></p>

<script type="text/javascript">
    var viewModel = {
        availableCountries: ko.observableArray(['France', 'Germany', 'Spain'])
    };
</script>

例3:Drop-down list展示的任意JavaScript對(duì)象,不僅僅是字符串

<p>
    Your country:
    <select data-bind="options: availableCountries, 
              optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"></select>
</p>

<div data-bind="visible: selectedCountry"> <!-- Appears when you select something -->
    You have chosen a country with population
    <span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>.
</div>

<script type="text/javascript">
    // Constructor for an object with two properties
var country =function (name, population) {
        this.countryName = name;
        this.countryPopulation = population;
    };

     var viewModel = {
        availableCountries: ko.observableArray([
            new country("UK", 65000000),
            new country("USA", 320000000),
            new country("Sweden", 29000000)
        ]),
        selectedCountry: ko.observable() // Nothing selected by default
    };
</script>

例4:Drop-down list展示的任意JavaScript對(duì)象,顯示text是function的返回值

<!-- Same as example 3, except the <select> box expressed as follows: -->

<select data-bind="options: availableCountries,
                   optionsText: function(item) {
                       return item.countryName + ' (pop: ' + item.countryPopulation + ')'
                   },
                   value: selectedCountry,
                   optionsCaption: 'Choose...'"></select>

注意例3和例4在optionsText值定義上的不同。

參數(shù)

????主參數(shù)

??? 該參數(shù)是一個(gè)數(shù)組(或者observable數(shù)組)。對(duì)每個(gè)item,KO都會(huì)將它作為一個(gè) 添加到里,之前的options都將被刪除。

??? 如果參數(shù)是一個(gè)string數(shù)組,那你不需要再聲明任何其它參數(shù)。元素會(huì)將每個(gè)string顯示為一個(gè)option。不過(guò),如果你讓用戶選擇的是一個(gè)JavaScript對(duì)象數(shù)組(不僅僅是string),那就需要設(shè)置optionsText和optionsValue這兩個(gè)參數(shù)了。

??? 如果參數(shù)是監(jiān)控屬性observable的,那元素的options項(xiàng)將根據(jù)參數(shù)值的變化而更新,如果不是,那元素的value值將只設(shè)置一次并且以后不在更新。

????其它參數(shù)

????????optionsCaption

??????? 有時(shí)候,默認(rèn)情況下不想選擇任何option項(xiàng)。但是single-select drop-down列表由于每次都要默認(rèn)選擇以項(xiàng)目,怎么避免這個(gè)問(wèn)題呢?常用的方案是加一個(gè)“請(qǐng)選擇的”或者“Select an item”的提示語(yǔ),或者其它類似的,然后讓這個(gè)項(xiàng)作為默認(rèn)選項(xiàng)。

??????? 我們使用optionsCaption參數(shù)就能很容易實(shí)現(xiàn),它的值是字符串型,作為默認(rèn)項(xiàng)顯示。例如:

???????

??????? KO會(huì)在所有選項(xiàng)上加上這一個(gè)項(xiàng),并且設(shè)置value值為undefined。所以,如果myChosenValue被設(shè)置為undefined(默認(rèn)是observable的),那么上述的第一個(gè)項(xiàng)就會(huì)被選中。

????????optionsText

??????? 上面的例3展示的綁定JavaScript對(duì)象到option上 – 不僅僅是字符串。這時(shí)候你需要設(shè)置這個(gè)對(duì)象的那個(gè)屬性作為drop-down列表或multi-select列表的text來(lái)顯示。例如,例3中使用的是設(shè)置額外的參數(shù)optionsText將對(duì)象的屬性名countryName作為顯示的文本。

??????? 如果不想僅僅顯示對(duì)象的屬性值作為每個(gè)item項(xiàng)的text值,那你可以設(shè)置optionsText 為JavaScript 函數(shù),然后再函數(shù)里通過(guò)自己的邏輯返回相應(yīng)的值(該函數(shù)參數(shù)為item項(xiàng)本身)。例4展示的就是返回item的2個(gè)屬性值合并的結(jié)果。

????????optionsValue

??????? 和optionsText類似, 你也可以通過(guò)額外參數(shù)optionsValue來(lái)聲明對(duì)象的那個(gè)屬性值作為該的value值。

??????? 經(jīng)典場(chǎng)景:如在更新options的時(shí)候想保留原來(lái)的已經(jīng)選擇的項(xiàng)。例如,當(dāng)你重復(fù)多次調(diào)用Ajax獲取car列表的時(shí)候,你要確保已經(jīng)選擇的某個(gè)car一直都是被選擇上,那你就需要設(shè)置optionsValue為“carId”或者其它的unique標(biāo)示符,否則的話KO找不知道之前選擇的car是新options里的哪一項(xiàng)。

????????selectedOptions

??????? 對(duì)于multi-select列表,你可以用selectedOptions讀取和設(shè)置多個(gè)選擇項(xiàng)。技術(shù)上看它是一個(gè)單獨(dú)的綁定,有自己的文檔,請(qǐng)參考: selectedOptions綁定。

注:已經(jīng)被選擇的項(xiàng)會(huì)再options改變的時(shí)候保留

當(dāng)使用options綁定元素的時(shí)候,如果options改變,KO將盡可能第保留之前已經(jīng)被選擇的項(xiàng)不變(除非是你事先手工刪除一個(gè)或多個(gè)已經(jīng)選擇的項(xiàng))。這是因?yàn)閛ptions 綁定嘗試依賴value值的綁定(single-select列表)和selectedOptions綁定(multi-select列表)。

依賴性

除KO核心類庫(kù)外,無(wú)依賴。

15 ? selectedOptions 綁定

目的

selectedOptions綁定用于控制multi-select列表已經(jīng)被選擇的元素,用在使用options綁定的元素上。

當(dāng)用戶在multi-select列表選擇或反選一個(gè)項(xiàng)的時(shí)候,會(huì)將view model的數(shù)組進(jìn)行相應(yīng)的添加或者刪除。同樣,如果view model上的這個(gè)數(shù)組是observable數(shù)組的話,你添加或者刪除任何item(通過(guò)push或者splice)的時(shí)候,相應(yīng)的UI界面里的option項(xiàng)也會(huì)被選擇上或者反選。這種方式是2-way綁定。

注:控制single-select下拉菜單選擇項(xiàng),你可以使用value綁定。

例子

<p>
    Choose some countries you'd like to visit:
    <select data-bind="options: availableCountries, selectedOptions: chosenCountries" size="5" multiple="true"></select>
</p>

<script type="text/javascript">
    var viewModel = {
        availableCountries: ko.observableArray(['France', 'Germany', 'Spain']),
        chosenCountries: ko.observableArray(['Germany']) // Initially, only Germany is selected
    }; 

    // ... then later ...
    viewModel.chosenCountries.push('France'); // Now France is selected too
</script>

參數(shù)

????主參數(shù)

??? 該參數(shù)是數(shù)組(或observable數(shù)組)。KO設(shè)置元素的已選項(xiàng)為和數(shù)組里match的項(xiàng),之前的已選擇項(xiàng)將被覆蓋。

??? 如果參數(shù)是依賴監(jiān)控屬性observable數(shù)組,那元素的已選擇項(xiàng)selected options項(xiàng)將根據(jù)參數(shù)值的變化(通過(guò)push,pop,或其它observable數(shù)組方法)而更新,如果不是,那元素的已選擇項(xiàng)selected options將只設(shè)置一次并且以后不在更新。

??? 不管該參數(shù)是不是observable數(shù)組,用戶在multi-select列表里選擇或者反選的時(shí)候,KO都會(huì)探測(cè)到,并且更新數(shù)組里的對(duì)象以達(dá)到同步的結(jié)果。這樣你就可以獲取options已選項(xiàng)。

????其它參數(shù)

??? ?????? 無(wú)

注:支持讓用戶選擇任意JavaScript對(duì)象

在上面的例子里,用戶可以選擇數(shù)組里的字符串值,但是選擇不限于字符串,如果你愿意你可以聲明包含任意JavaScript對(duì)象的數(shù)組,查看options綁定如何顯示JavaScript對(duì)象到列表里。

這種場(chǎng)景,你可以用selectedOptions來(lái)讀取或設(shè)置這些對(duì)象本身,而不是頁(yè)面上顯示的option表示形式,這樣做在大部分情況下都非常清晰。view model就可以探測(cè)到你從數(shù)組對(duì)象里選擇的項(xiàng)了,而不必關(guān)注每個(gè)項(xiàng)和頁(yè)面上展示的option項(xiàng)是如何map的。

依賴性

除KO核心類庫(kù)外,無(wú)依賴。

16 ? uniqueName 綁定

目的

uniqueName綁定確保所綁定的元素有一個(gè)非空的name屬性。如果該元素沒(méi)有name屬性,那綁定會(huì)給它設(shè)置一個(gè)unique的字符串值作為name屬性。你不會(huì)經(jīng)常用到它,只有在某些特殊的場(chǎng)景下才用到,例如:

  • 在使用KO的時(shí)候,一些技術(shù)可能依賴于某些元素的name屬性,盡快他們沒(méi)有什么意義。例如,jQuery Validation驗(yàn)證當(dāng)前只驗(yàn)證有name屬性的元素。為配合Knockout UI使用,有些時(shí)候需要使用uniqueName綁定避免讓jQuery Validation驗(yàn)證出錯(cuò)。

  • IE 6下,如果radio button沒(méi)有name屬性是不允許被checked了。大部分時(shí)候都沒(méi)問(wèn)題,因?yàn)榇蟛糠謺r(shí)候radio button元素都會(huì)有name屬性的作為一組互相的group。不過(guò),如果你沒(méi)聲明,KO內(nèi)部會(huì)在這些元素上使用uniqueName那么以確保他們可以被checked。

例子

<input data-bind="value: someModelProperty, uniqueName: true"/>

參數(shù)

????主參數(shù)

??? 就像上面的例子一樣,傳入true(或者可以轉(zhuǎn)成true的值)以啟用uniqueName綁定。

????其它參數(shù)

??????? 無(wú)

依賴性

除KO核心類庫(kù)外,無(wú)依賴。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)