4.Knockout.Js(事件綁定)

前言javascript

click綁定在DOM元素上添加事件句柄以便元素被點擊的時候執行定義的JavaScript 函數。大部分是用在button,input和鏈接a上,可是能夠在任意元素上使用。html

簡單示例java

複製代碼
<h2>ClickBind</h2>
<div>
    You've clicked <span data-bind="text: numberOfClicks"></span> times <button data-bind="click: incrementClickCounter">Click me</button> </div> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { numberOfClicks: ko.observable(0), incrementClickCounter: function() { var previousCount = this.numberOfClicks(); this.numberOfClicks(previousCount + 1); } }; ko.applyBindings(viewModel); </script>
複製代碼

預覽效果數組

  

每次點擊按鈕的時候,都會調用incrementClickCounter()函數,而後更新自動更新點擊次數。瀏覽器

你能夠聲明任何JavaScript函數 – 不必定非要是view model裏的函數。你能夠聲明任意對象上的任何函數,例如: someObject.someFunction。服務器

View model上的函數在用的時候有一點點特殊,就是不須要引用對象的,直接引用函數自己就好了,好比直接寫incrementClickCounter 就能夠了,而無需寫成: viewModel.incrementClickCounter(儘管是合法的)。app

傳參數給你的click 句柄異步

 最簡單的辦法是傳一個function包裝的匿名函數:函數

<button data-bind="click: function() { viewModel.myFunction('param1', 'param2') }"> Click me </button>

這樣,KO就會調用這個匿名函數,裏面會執行viewModel.myFunction(),而且傳進了'param1' 和'param2'參數。post

訪問事件源對象

 有些狀況,你可能須要使用事件源對象,Knockout會將這個對象傳遞到你函數的第一個參數:

複製代碼
<button data-bind="click: myFunction"> Click me event </button> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { numberOfClicks: ko.observable(0), incrementClickCounter: function() { var previousCount = this.numberOfClicks(); this.numberOfClicks(previousCount + 1); }, myFunction: function (event) { //////  } }; ko.applyBindings(viewModel); </script>
複製代碼

若是你須要的話,可使用匿名函數的第一個參數傳進去,而後在裏面調用:

<button data-bind="click: function(event) { viewModel.myFunction(event, 'param1', 'param2') }"> Click me </button>

這樣,KO就會將事件源對象傳遞給你的函數而且使用了。

容許執行默認事件

默認狀況下,Knockout會阻止冒泡,防止默認的事件繼續執行。例如,若是你點擊一個a鏈接,在執行完自定義事件時它不會鏈接到href地址。這特別有用是由於你的自定義事件主要就是操做你的view model,而不是鏈接到另一個頁面。

固然,若是你想讓默認的事件繼續執行,你能夠在你click的自定義函數裏返回true。

防止事件冒泡

默認狀況下,Knockout容許click事件繼續在更高一層的事件句柄上冒泡執行。例如,若是你的元素和父元素都綁定了click事件,那當你點擊該元素的時候兩個事件都會觸發的。若是須要,你能夠經過額外的綁定clickBubble來禁止冒泡。例如:

<div data-bind="click: myDivHandler"> <button data-bind="click: myButtonHandler, clickBubble: false"> Click me </button> </div>

默認狀況下,myButtonHandler會先執行,而後會冒泡執行myDivHandler。但一旦你設置了clickBubble爲false的時候,冒泡事件會被禁止

Knockout.Js官網學習(event綁定、submit綁定)

event綁定

event綁定在DOM元素上添加指定的事件句柄以便元素被觸發的時候執行定義的JavaScript 函數。大部分狀況下是用在keypress,mouseover和mouseout上。

簡單示例

 

複製代碼
<div>
    <div data-bind="event: { mouseover: enableDetails, mouseout: disableDetails }"> Mouse over me </div> <div data-bind="visible: detailsEnabled"> Details </div> </div> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { detailsEnabled: ko.observable(false), enableDetails:function() { this.detailsEnabled(true); }, disableDetails:function () { this.detailsEnabled(false); } }; ko.applyBindings(viewModel); </script>
複製代碼

就是經過在一個div上綁定兩個事件,一個鼠標點上去的mouseover讓下面的div內容顯示出來,另外一個是鼠標移出mouseout讓下面的div內容再隱藏。

你能夠聲明任何JavaScript函數 – 不必定非要是view model裏的函數。你能夠聲明任意對象上的任何函數,例如: event: { mouseover: someObject.someFunction }。

View model上的函數在用的時候有一點點特殊,就是不須要引用對象的,直接引用函數自己就好了,好比直接寫event: { mouseover: enableDetails } 就能夠了,而無需寫成: event: { mouseover: viewModel.enableDetails }(儘管是合法的)。

submit綁定

 submit綁定在form表單上添加指定的事件句柄以便該form被提交的時候執行定義的JavaScript 函數。只能用在表單form元素上。

 

 當你使用submit綁定的時候, Knockout會阻止form表單默認的submit動做。換句話說,瀏覽器會執行你定義的綁定函數而不會提交這個form表單到服務器上。能夠很好地 解釋這個,使用  submit綁定就是爲了處理view model的自定義函數的,而不是再使用普通的HTML form表單。若是你要繼續執行默認的HTML form表單操做,你能夠在你的submit句柄裏返回true。

submit簡單示例

<form data-bind="submit: doSomething"> ... form contents go here ... <input type="text" value="1" id="test"/> <button type="submit">Submit</button> </form>

簡單的UI元素

        doSomething: function (formElement) {
            alert(formElement[0].outerHTML); }

簡單的viewModel屬性

總共有兩個元素一個是錄入框,另外一個是submit提交按鈕

在form上,你可使用click綁定代替submit綁定。不過submit能夠handle其它的submit行爲,好比在輸入框裏輸入回車的時候能夠提交表單。

Knockout.Js官網學習(enable綁定、disable綁定)

enable綁定

enable綁定使DOM元素只有在參數值爲 true的時候才enabled。在form表單元素input,select,和textarea上很是有用。

enable簡單示例

 

複製代碼
<h2>enableBind</h2>
<p>    <input type='checkbox' data-bind="checked: hasCellphone"/> I have a cellphone</p> <p> Your cellphone number: <input type='text' data-bind="value: cellphoneNumber, enable: hasCellphone"/></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { hasCellphone: ko.observable(false), cellphoneNumber:ko.observable("") }; ko.applyBindings(viewModel); </script>
複製代碼

這個例子裏,「Your cellphone number」後的text box 初始狀況下是禁用的,只有當用戶點擊標籤 「I have a cellphone」的時候纔可用。

聲明DOM元素是否可用enabled。

非布爾值會被解析成布爾值。例如0和null被解析成false,21和非null對象被解析給true。

若是你的參數是observable的,那綁定會隨着observable值的改變而自動更新enabled/disabled狀態。若是不是,則只會設置一次而且之後再也不更新。

任意使用JavaScript表達式

 不牢牢限制於變量 – 你可使用任何JavaScript表達式來控制元素是否可用。例如

<button data-bind="enable: parseAreaCode(viewModel.cellphoneNumber()) != '555'"> 
  Do something
</button>

disable綁定

disable綁定使DOM元素只有在參數值爲 true的時候才disabled。在form表單元素input,select,和textarea上很是有用。

disable綁定和enable綁定正好相反,詳情請參考enable綁定

Knockout.Js官網學習(value綁定)

前言

value綁定是關聯DOM元素的值到view model的屬性上。主要是用在表單控件<input>,<select>和<textarea>上。

當用戶編輯表單控件的時候, view model對應的屬性值會自動更新。一樣,當你更新view model屬性的時候,相對應的元素值在頁面上也會自動更新。

注:若是你在checkbox或者radio button上使用checked綁定來讀取或者寫入元素的 checked狀態,而不是value 值的綁定。

簡單示例

 代碼以下對兩個input進行value的屬性綁定

複製代碼
<p>Login name: <input data-bind="value: userName"/></p> <p>Password: <input type="password" data-bind="value: userPassword"/></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { userName: ko.observable(""), userPassword: ko.observable("abc") }; ko.applyBindings(viewModel); </script> 
複製代碼

運行後效果爲

注意密碼的type爲password

KO設置此參數爲元素的value值。以前的值將被覆蓋。

    若是參數是監控屬性observable的,那元素的value值將根據參數值的變化而更新,若是不是,那元素的value值將只設置一次而且之後不在更新。

    若是你提供的參數不是一個數字或者字符串(而是對象或者數組)的話,那顯示的value值就是yourParameter.toString() 的內容(一般沒用,因此最好都設置爲數字或者字符串)。

    無論何時,只要你更新了元素的值,那 KO都會將view model對應的屬性值自動更新。默認狀況下當用戶離開焦點(例如onchange事件)的時候,KO才更新這個值,可是你能夠經過第2個參數valueUpdate來特別指定改變值的時機。

valueUpdate

  若是你使用valueUpdate參數,那就是意味着KO將使用自定義的事件而不是默認的離開焦點事件。下面是一些最經常使用的選項:

            「change」(默認值) - 當失去焦點的時候更新view model的值,或者是<select> 元素被選擇的時候。

            「keyup」 – 當用戶敲完一個字符之後當即更新view model。

            「keypress」 – 當用戶正在敲一個字符但沒有釋放鍵盤的時候就當即更新view model。不像 keyup,這個更新和keydown是同樣的。

            「afterkeydown」 – 當用戶開始輸入字符的時候就更新view model。主要是捕獲瀏覽器的keydown事件或異步handle事件。

        上述這些選項,若是你想讓你的view model進行實時更新,使用「afterkeydown」是最好的選擇。

<p>Your value: <input data-bind="value: someValue, valueUpdate: 'afterkeydown'"/></p> <p>You have typed: <span data-bind="text: someValue"></span></p>
someValue: ko.observable("edit me")

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

 Knockout對下拉菜單drop-down list綁定有一個特殊的支持,那就是在讀取和寫入綁定的時候,這個值能夠是任意JavaScript對象,而沒必要非得是字符串。在你讓你用戶選擇一組model對象的時候很是有用。具體例子,參考options綁定。

相似,若是你想建立一個multi-select list,參考selectedOptions綁定。

更新observable和non-observable屬性值

 若是你用value綁定將你的表單元素和你的observable屬性關聯起來,KO設置的2-way的雙向綁定,任何一方改變都會更新另一方的值。

 可是,若是你的元素綁定的是一個non-observable屬性(例如是一個原始的字符串或者JavaScript表達式) ,KO會這樣執行:

  1.若是你綁定的non-observable屬性是簡單對象,例如一個常見的屬性值,KO會設置這個值爲form表單元素的初始值,若是你改 變form表單元素的值,KO會將值從新寫回到view mode的這個屬性。但當這個屬性本身改變的時候,元素卻不會再變化了(由於不是observable的),因此它僅僅是1-way綁定。

  2.若是你綁定的non-observable屬性是複雜對象,例如複雜的JavaScript 表達式或者子屬性,KO也會設置這個值爲form表單元素的初始值,可是改變form表單元素的值的時候,KO不會再寫會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"// Not observable  }; ko.applyBindings(viewModel); </script>
複製代碼

 Knockout.Js官網學習(checked 綁定)

前言

checked綁定是關聯到checkable的form表單控件到view model上 - 例如checkbox(<input type='checkbox'>)或者radio button(<input type='radio'>) 。當用戶check關聯的form表單控件的時候,view model對應的值也會自動更新,相反,若是view model的值改變了,那控件元素的check/uncheck狀態也會跟着改變。

注:對text box,drop-down list和全部non-checkable的form表單控件,用value綁定來讀取和寫入是該元素的值,而不是checked綁定。

簡單示例

 示例代碼

複製代碼
<p>Send me spam:<input type="checkbox" data-bind="checked:wantsSpam" /></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { wantsSpam:ko.observable(true) }; viewModel.wantsSpam(false); ko.applyBindings(viewModel); </script>
複製代碼

運行以後

 對於checkbox,當參數爲true的時候,KO會設置元素的狀態爲checked,反正設置爲unchecked。若是你傳的參數不是布爾值,那KO將會解析成布爾值。也就是說非0值和非null對象,非空字符串將被解析成true,其它值都被解析成false。

當用戶check或者uncheck這個checkbox的時候,KO會將view model的屬性值相應地設置爲true或者false。

Checkbox關聯到數組

複製代碼
<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" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { wantsSpam: ko.observable(true), spamFlavors: ko.observableArray(["cherry", "almond"]) }; ko.applyBindings(viewModel); viewModel.wantsSpam(false); viewModel.spamFlavors.push("msg"); </script
複製代碼

添加radio button

    <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>

 

spamFlavor:ko.observable("cherry")

對於radio buttons,KO只有當參數值等於radio button value屬性值的時候才設置元素爲checked狀態。因此參數應是字符串。在上面的例子裏只有當view model 的spamFlavor 屬性等於「almond」的時候,該radio button纔會設置爲checked。

固然,最有用的是設置一組radio button元素對應到一個單個的view model 屬性。確保一次只能選擇一個radio button須要將他們的name屬性名都設置成同樣的值(例如上個例子的flavorGroup值)。這樣的話,一次就只能選擇一個了。

若是參數是監控屬性observable的,那元素的checked狀態將根據參數值的變化而更新,若是不是,那元素的value值將只設置一次而且之後不在更新

Knockout.Js官網學習(options綁定)

前言

options綁定控制什麼樣的options在drop-down列表裏(例如:<select>)或者 multi-select 列表裏 (例如:<select size='6'>)顯示。此綁定不能用於<select>以外的元素。關聯的數據應是數組(或者是observable數組),& lt;select>會遍歷顯示數組裏的全部的項。

對於multi-select列表,設置或者獲取選擇的多項須要使用selectedOptions綁定。對於single-select列表,你也可使用value綁定讀取或者設置元素的selected項。

Drop-down list

 

複製代碼
<p>Destination country: <select data-bind="options: availableCountries"></select></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) }; ko.applyBindings(viewModel); viewModel.availableCountries.push('China'); </script>
複製代碼

 

該參數是一個數組(或者observable數組)。對每一個item,KO都會將它做爲一個<option> 添加到<select>裏,以前的options都將被刪除。

若是參數是一個string數組,那你不須要再聲明任何其它參數。<select>元素會將每一個string顯示爲一個option。 不過,若是你讓用戶選擇的是一個JavaScript對象數組(不只僅是string),那就須要設置optionsText和optionsValue 這兩個參數了。

若是參數是監控屬性observable的,那元素的options項將根據參數值的變化而更新,若是不是,那元素的value值將只設置一次而且之後不在更新。

 

若是對上面的select UI元素加上multiple="true"

<select data-bind="options: availableCountries" multiple="true"></select>

這能夠說是Multi-select list

Drop-down list展現的任意JavaScript對象,不只僅是字符串

 

複製代碼
<p>Destination country: <select data-bind="options: availableCountries" multiple="true"></select></p> <p> Your country: <select data-bind="options: Countries,optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"> </select> </p> <div data-bind="visible: selectedCountry"> You have chosen a country with population <span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>. </div> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var Country = function (name, population) { this.countryName = name; this.countryPopulation = population; }; var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']), selectedCountry: ko.observable(), Countries: ko.observableArray([ new Country("UK", 65000000), new Country("USA", 320000000), new Country("Sweden", 29000000) ]) }; ko.applyBindings(viewModel); viewModel.availableCountries.push('China'); </script>
複製代碼

optionsCaption

有時候,默認狀況下不想選擇任何option項。可是single-select drop-down列表因爲每次都要默認選擇以項目,怎麼避免這個問題呢?經常使用的方案是加一個「請選擇的」或者「Select an item」的提示語,或者其它相似的,而後讓這個項做爲默認選項。

咱們使用optionsCaption參數就能很容易實現,它的值是字符串型,做爲默認項顯示。例如:

<select data-bind='options: myOptions, optionsCaption: "Select an item...", value: myChosenValue'></select>

KO會在全部選項上加上這一個項,而且設置value值爲undefined。因此,若是myChosenValue被設置爲undefined(默認是observable的),那麼上述的第一個項就會被選中

Drop-down list展現的任意JavaScript對象,顯示text是function的返回值

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

optionsText

上面《Drop-down list展現的任意JavaScript對象,不只僅是字符串》中展現的綁定 JavaScript對象到option上 – 不只僅是字符串。這時候你須要設置這個對象的那個屬性做爲drop-down列表或multi-select列表的text來顯示。設置額外的參數 optionsText將對象的屬性名countryName做爲顯示的文本。

若是不想僅僅顯示對象的屬性值做爲每一個item項的text值,那你能夠設置optionsText 爲JavaScript 函數,而後再函數裏經過本身的邏輯返回相應的值(該函數參數爲item項自己)。

optionsValue

和optionsText相似, 你也能夠經過額外參數optionsValue來聲明對象的那個屬性值做爲該<option>的value值。

經典場景:如在更新options的時候想保留原來的已經選擇的項。例如,當你重複屢次調用Ajax獲取car列表的時候,你要確保已經選擇的某個 car一直都是被選擇上,那你就須要設置optionsValue爲「carId」或者其它的unique標示符,不然的話KO找不知道以前選擇的car 是新options裏的哪一項

selectedOptions

對於multi-select列表,你能夠用selectedOptions讀取和設置多個選擇項。技術上看它是一個單獨的綁定,有本身的文檔,請參考: selectedOptions綁定。

Knockout.Js官網學習(selectedOptions綁定、uniqueName 綁定)

selectedOptions綁定

selectedOptions綁定用於控制multi-select列表已經被選擇的元素,用在使用options綁定的<select>元素上。

當用戶在multi-select列表選擇或反選一個項的時候,會將view model的數組進行相應的添加或者刪除。一樣,若是view model上的這個數組是observable數組的話,你添加或者刪除任何item(經過push或者splice)的時候,相應的UI界面裏的 option項也會被選擇上或者反選。這種方式是2-way綁定。

注:控制single-select下拉菜單選擇項,你可使用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" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']), chosenCountries: ko.observableArray(['Germany']) }; ko.applyBindings(viewModel); viewModel.chosenCountries.push('France'); </script>
複製代碼

該參數是數組(或observable數組)。KO設置元素的已選項爲和數組裏match的項,以前的已選擇項將被覆蓋。

若是參數是依賴監控屬性observable數組,那元素的已選擇項selected options項將根據參數值的變化(經過push,pop,或其它observable數組方法)而更新,若是不是,那元素的已選擇項selected options將只設置一次而且之後不在更新。

無論該參數是否是observable數組,用戶在multi-select列表裏選擇或者反選的時候,KO都會探測到,而且更新數組裏的對象以達到同步的結果。這樣你就能夠獲取options已選項。

支持讓用戶選擇任意JavaScript對象

在上面的例子裏,用戶能夠選擇數組裏的字符串值,可是選擇不限於字符串,若是你願意你能夠聲明包含任意JavaScript對象的數組,查看options綁定如何顯示JavaScript對象到列表裏。

這種場景,你能夠用selectedOptions來讀取或設置這些對象自己,而不是頁面上顯示的option表示形式,這樣作在大部分狀況下都非 常清晰。view model就能夠探測到你從數組對象裏選擇的項了,而沒必要關注每一個項和頁面上展現的option項是如何map的。

uniqueName綁定

 uniqueName綁定確保所綁定的元素有一個非空的name屬性。若是該元素沒有name屬性,那綁定會給它設置一個unique的字符串值做爲name屬性。你不會常常用到它,只有在某些特殊的場景下才用到。

  1.在使用KO的時候,一些技術可能依賴於某些元素的name屬性,儘快他們沒有什麼意義。例如,jQuery Validation驗證當前只驗證有name屬性的元素。爲配合Knockout UI使用,有些時候須要使用uniqueName綁定避免讓jQuery Validation驗證出錯。

  2.IE 6下,若是radio button沒有name屬性是不容許被checked了。大部分時候都沒問題,由於大部分時候radio button元素都會有name屬性的做爲一組互相的group。不過,若是你沒聲明,KO內部會在這些元素上使用uniqueName那麼以確保他們可 以被checked。

 例如:

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

 就像上面的例子同樣,傳入true(或者能夠轉成true的值)以啓用uniqueName綁定。

相關文章
相關標籤/搜索