做爲一名初學者來講,一篇篇的按順序看官網上的文檔的確是一件很痛苦的事情,畢竟它的排列也並不是是由淺及深的排列,其中的順序也頗回味無窮,因而這篇文章我又跳過了Reference部分,進而進入到具體的bindings環節,首先接觸到的是Controlling text and appearance。javascript
Visible binding會依據綁定的數據來決定相應的DOM元素是否隱藏。css
咱們首先在js文件部分定義一個view model,這裏我建立的是一個object而不是一個構造函數,我的分析認爲,object類型的定義就是一種persistent view model,而構造函數類型的定義就是一種temporary view model,這個也許和pure computed observables中的性能有關,可和knockout學習筆記(四)聯繫起來。html
相應的js部分以下:java
1 var myViewModel = { 2 shouldShowMessage: ko.observable() 3 } 4 5 ko.applyBindings(myViewModel);
在html部分的測試元素以下:web
1 <p data-bind="visible: shouldShowMessage">Test for visible binding</p>
在這種狀況下,因爲我沒有給shouldShowMessage賦一個初始值,因此應該是undefined,即對應的false,實際上頁面顯示出來的是:安全
能夠看出咱們添加的p元素並無顯示出來,接下來我在js部分修改了shouldShowMessage的值:app
1 myViewModel.shouldShowMessage(true);
頁面變成了這樣:函數
此時的頁面中顯示出了p元素。性能
有關visible binding的參數:當參數是false或至關於false的值時,binding會將yourElement.style.display設置爲none使得訂閱的元素隱藏,而這個設定也會覆蓋掉全部你本身定義的CSS樣式,我猜想這是和CSS樣式覆蓋規則有關,knockoutjs也許就是將這一個賦值的優先級設置爲最高或者是合理利用了相應的順序,這個能夠之後研究knockoutjs的源碼的時候查一查。當參數是true或是至關於true的值時,binding會刪去相應的yourElement.style.display,從而讓用戶自定義的CSS樣式做用於訂閱的元素上。學習
當參數是一個observable時,每當參數變化,UI部分的元素都會更新本身的visible屬性,而當參數不是observable時,UI部分的元素只會對visible屬性設定一次。固然,參數也能夠是一個函數,binding會根據function返回的值是true仍是false來決定是否顯示相應的DOW element。
Text binding會使得相應的DOM element的text部分變爲參數的值。
js部分的代碼以下:
1 var myViewModel = { 2 myText: ko.observable() 3 } 4 5 ko.applyBindings(myViewModel); 6 7 myViewModel.myText("Hello world!");
html部分的代碼以下:
1 <p>This is my text: <span data-bind="text: myText"></span></p>
頁面顯示效果以下:
利用text binding的時候,element所訂閱的view model的值會覆蓋掉html中現有的text部分,若是參數是一個observable,每當參數變化的時候,UI都會更新本身的text部分,而若是參數不是observable,UI只會在最初的時候設定好text,之後再也不更新。若是參數不是數字類型也不是字符串類型,則binding會調用yourParameter.toString()來將其轉換爲text再替換掉text部分的內容。
注意一:若是咱們但願經過函數來計算或者說控制輸出到text部分的值,咱們能夠將其綁定至一個computed observable,js部分以下:
1 var myViewModel = { 2 myText: ko.observable(), 3 myComputed: ko.pureComputed(function() { 4 return myViewModel.myText() > 50 ? "Big" : "Small"; 5 }) 6 } 7 8 ko.applyBindings(myViewModel); 9 10 myViewModel.myText(60);
html部分以下:
1 <p>This is my text: <span data-bind="text: myComputed"></span></p>
頁面效果以下:
在上例中的view model是做爲object直接聲明的,這是爲了可以方便地更改其中的屬性(myText)。若是將上例中的myViewModel.myText替換爲this.myText,必然會報錯,由於以前的文章已經提到過,function並不能算做是object的一部分,不過computed提供了一個指定this的值的方式,若是修改爲如下模樣:
1 var myViewModel = { 2 myText: ko.observable(), 3 myComputed: ko.pureComputed(function() { 4 return this.myText() > 50 ? "Big" : "Small"; 5 }, this) 6 }
結果依然會報錯:undefined is not a function。這裏也許須要理清的就是函數中的this和object中的this的問題,留做之後研究。以後我換了一種方式,換成了構造函數:
1 function MyViewModel(myText) { 2 this.myText = ko.observable(myText); 3 this.myComputed = ko.pureComputed(function() { 4 return this.myText() > 50 ? "Big" : "Small"; 5 }, this); 6 }
這樣是可行的,我就猜測會不會是以前的例子裏沒有給屬性添加this,經測試,object裏面徹底不支持this,這也是本身對javascript的理解不清晰所致,因而能夠認爲,在object的定義形式中,computed內所關聯的observable需帶上這個view model的全名,而在function的定義形式中,則可使用this來指代當前的實例。這裏又涉及到這兩種定義方式的區別問題,留做之後研究。
固然,咱們也能夠直接將computed部分最後返回的結果用data-bind來綁定,以下:
1 <p>This is my text: <span data-bind="text: myText > 50 ? 'Big' : 'Small'"></span></p>
這樣咱們就不須要再定義一個computed observable。
注意二:若是咱們傳入text的參數中含有html的標籤,頁面中並不會將其以標籤的形式展示,而是會以字符串的方式展示出來,例如:
1 myViewModel.myText("<i>Hello world!</i>");
顯示出來會是:
這樣也能夠防止HTML或是script的注入攻擊。而有關html標籤的綁定則須要參考html binding。
注意三:在某些時候,咱們須要在不指定元素的狀況下直接插入text,此時咱們可使用無容器的語法來定義一個text binding。例如在option element中是不容許包含其餘元素的,若是咱們以下定義data-bind
1 <select> 2 <option>Item <span data-bind="text: myText"></span></option> 3 </select>
咱們並不能獲得view model中的observable,無容器的語法則是這樣寫的:
1 <select> 2 <option>Item <!--ko text: myText--><!--/ko--></option> 3 </select>
<!--ko-->和<!--/ko-->扮演着開始標誌和結束標誌,它們定義了一個虛擬元素,knockout語法可以理解這種寫法並像對待一個最真實元素那樣去綁定相應的view model內的值。
Html binding其實與text binding相似,只不過它的參數通常是帶有html標籤的,這樣就能夠自定義想要綁定的html元素。
下面是個很簡單的例子:
1 var myViewModel = { 2 myHtml: ko.observable(), 3 } 4 5 ko.applyBindings(myViewModel); 6 7 myViewModel.myHtml("<a href='http://www.google.com'>Google</a>");
html部分以下:
1 <p>My html element is: <span data-bind="html: myHtml"></span></p>
頁面的效果以下:
html binding的其餘特性與text binding相似,可是使用html binding的時候要特別注意安全問題,防止注入式攻擊等。
CSS binding主要用於根據view model的修改來更改UI中相應元素的class,從而依照CSS文件中已經定義好的樣式來體如今頁面中。一個簡單的static css binding例子以下:
js部分:
1 var myViewModel = { 2 myTest : ko.observable(), 3 } 4 5 ko.applyBindings(myViewModel); 6 7 myViewModel.myTest(20);
html部分:
1 <p data-bind="css: { redText: myTest() > 0 }">Test for css binding</p>
css部分:
1 .redText { 2 color: red; 3 }
頁面顯示效果以下:
另外,咱們也能夠經過綁定一個computed observable來動態指定css class的值,這樣的綁定稱爲dynamic css binding,簡單的例子以下:
js部分:
1 var myViewModel1 = { 2 myTest: ko.observable(), 3 myComputed: ko.pureComputed(function() { 4 return myViewModel1.myTest() > 0 ? "redText" : "blueText"; 5 }) 6 }; 7 8 var myViewModel2 = { 9 myTest: ko.observable(), 10 myComputed: ko.pureComputed(function() { 11 return myViewModel2.myTest() > 0 ? "redText" : "blueText"; 12 }) 13 }; 14 15 ko.applyBindings(myViewModel1, document.getElementById("redText")); 16 ko.applyBindings(myViewModel2, document.getElementById("blueText")); 17 18 myViewModel1.myTest(20); 19 myViewModel2.myTest(-20);
html部分:
1 <p id="redText" data-bind="css: myComputed">This is red text.</p> 2 <p id="blueText" data-bind="css: myComputed">This is blue text.</p>
css部分:
1 .redText { 2 color: red; 3 } 4 5 .blueText { 6 color: blue; 7 }
頁面顯示效果以下:
css bidning是十分靈活的,對於static css binding,咱們通常是以data-bind="css: {cssClass: viewModelProperty}"的形式來綁定css class,cssClass會根據viewModelProperty返回的值是true仍是false來決定這個class如今是否須要使用。另外,咱們也能夠一次性設置多個css classes,簡單的示例以下:
js部分:
1 var myViewModel = { 2 redTextDecision: ko.observable(), 3 textDecorationDecision: ko.observable() 4 }; 5 6 ko.applyBindings(myViewModel); 7 8 myViewModel.redTextDecision(true); 9 myViewModel.textDecorationDecision(true);
html部分:
1 <p data-bind="css: {redText: redTextDecision, textDecoration: textDecorationDecision}">This is red text, and its text-decoration is underline.</p>
css部分:
1 .redText { 2 color: red; 3 } 4 5 .textDecoration { 6 text-decoration: underline; 7 }
頁面顯示效果以下:
在上例中,咱們是使用兩個view model的property來決定兩個不一樣的css class,KO也容許咱們使用一個view model property來決定多個css class,可將上例的html部分改爲以下形式:
1 <p data-bind="css: {'redText textDecoration': redTextDecision}">This is red text, and its text-decoration is underline.</p>
這裏爲了簡便,並無更改相應的view model property的名稱,能夠看到,當對多個css class進行設定的時候,咱們須要將它們統一包含在引號中。
若是綁定的view model property屬性是一個observable,則UI會根據該observable的變化來動態的增長或刪去被綁定的css class,不然,UI只會在開始階段設定一次css class,以後再也不更新。
dynamic css binding的通常形式是這樣的:data-bind="css: viewModelProperty",UI會根據viewModelProperty返回的字符串(property自己能夠是一個表明css class的字符串)來決定添加的css class的名稱。若是property是一個observable,則在該observable改變的時候,UI會刪去以前該observable所添加的class並從新設置爲當前observable的值。在dynamic css binding中,咱們可讓viewModelProperty添加多個css class,只需將這些css class以空格分開並統一以字符串的方式返回便可。一個簡單的例子以下:
js部分:
1 var myViewModel = { 2 textDecorationDecision: ko.observable("textDecoration redText") 3 }; 4 5 ko.applyBindings(myViewModel);
html部分:
1 <p data-bind="css: textDecorationDecision">This is red text, and its text-decoration is underline.</p>
頁面顯示效果以下:
對於某些帶有特殊符號的css class,好比red-text,咱們不能直接在data-bind中以data-bind="css: {red-text: redTextDecision}"的方式來設定,而是應該在這類css class外添加一對引號使其成爲字符串常量,變成這樣:data-bind="css: {'red-text': redTextDecision}"。
style binding是與css binding不一樣的控制頁面樣式的方式,css binding須要依賴css文件中對應的樣式表,藉由增長或刪除css class來改變樣式,而style binding則是直接在相應的元素上添加或刪除style來改變頁面的樣式。一個簡單的例子以下:
js部分:
1 var myViewModel = { 2 redTextDecision: ko.observable("red") 3 }; 4 5 ko.applyBindings(myViewModel);
html部分:
1 <p data-bind="style: {color: redTextDecision}">This is red text.</p>
頁面顯示效果以下:
與css binding相似,咱們也能夠一次性設定多個style,以下:
1 <p data-bind="style: {color: redTextDecision, align: alignDecision}">This is red text.</p>
若是綁定的viewModelProperty是一個observable,則每次observable改變的同時,UI會對對應的style進行更新;不然,UI只會設定一次style,以後再也不改變。
有些style是帶有特殊符號的,好比"text-decoration",好比"font-size"。在這種狀況下,直接在data-bind中填寫style的原名是不妥的,咱們須將其變動爲"textDecoration"和"fontSize",其餘相似的情形以此類推。
attr binding用於綁定某些元素的attribute,好比說a元素的title、href,img元素的src等。一個簡單的例子以下:
js部分:
1 var myViewModel = { 2 url: ko.observable("http://www.google.com"), 3 description: ko.observable("This is google's website"), 4 imgUrl: ko.observable("YukiNagato.JPG") 5 }; 6 7 ko.applyBindings(myViewModel);
html部分:
1 <a data-bind="attr {href: url, title: description}">Google's website</a> 2 <img style="weight: 100px; height: 100px" data-bind="attr {src: imgUrl}" />
頁面顯示效果以下:
若是綁定的viewModelProperty是一個observable,則每次observable改變時,UI均會更新相應的attribute;不然,UI只會設定一次attribute,以後再也不更新。
當attribute name中帶有連字符號時,咱們只需在其外部添加一對引號便可。