(二)Knockout 文本與外觀綁定

Visible

Visible binding會依據綁定的數據來決定相應的DOM元素是否隱藏,hidden或visible。javascript

咱們首先在js文件部分定義一個view model,這裏我建立的是一個object而不是一個構造函數,我的分析認爲,object類型的定義就是一種persistent view model,而構造函數類型的定義就是一種temporary view model,這個也許和pure computed observables中的性能有關,可和knockout學習筆記(四)聯繫起來。css

<div data-bind="visible: shouldShowMessage">
      You will see this message only when "shouldShowMessage" holds a true
      value.
    </div>
    
    <script>
        var viewModel = {
          shouldShowMessage: ko.observable(true) // Message initially visible
        };
        viewModel.shouldShowMessage(false); //隱藏元素
        //viewModel.shouldShowMessage(true);  //顯示元素
        ko.applyBindings(viewModel);
      </script>

text

Text binding會使得相應的DOM element的text部分變爲參數的值。html

<p>This is my text: <span data-bind="text: myText"></span></p>

    <script>
      var myViewModel = {
        myText: ko.observable()
      };

      ko.applyBindings(myViewModel);

      myViewModel.myText("Hello world!");
      ko.applyBindings(viewModel);
    </script>

輸出結果:java

This is my text: Hello world!web

備註 1 : 使用函數和值表達式

<p>This is my text: <span data-bind="text: myComputed"></span></p>
    
    <script type="text/javascript">
      var viewModel = {
        myText: ko.observable(60),
      };

      viewModel.myComputed = ko.pureComputed(function () {
        return this.myText() > 50 ? "Big" : "Small";
      }, viewModel);

      ko.applyBindings(viewModel);

    </script>

輸出結果:app

This is my text: Big函數

備註2:關於HTML編碼

若是咱們傳入text的參數中含有html的標籤,頁面中並不會將其以標籤的形式展示,而是會以字符串的方式展示出來,例如:性能

myViewModel.myText("<i>Hello world!</i>");

輸出結果:學習

This is my text: <i>Hello world!</i>this

這樣也能夠防止HTML或是script的注入攻擊。而有關html標籤的綁定則須要參考html binding

備註3:無容器

在某些時候,咱們須要在不指定元素的狀況下直接插入text,此時咱們可使用無容器的語法來定義一個text binding。例如在option element中是不容許包含其餘元素的,若是咱們以下定義data-bind

<select>
 <option>Item <span data-bind="text: myText"></span></option>
 </select>

咱們並不能獲得view model中的observable,無容器的語法則是這樣寫的:

<select data-bind="foreach: myItems">
    <option>Item <!--ko text: name--><!--/ko--></option>
</select>

<!--ko--><!--/ko-->扮演着開始標誌和結束標誌,它們定義了一個虛擬元素,knockout語法可以理解這種寫法並像對待一個最真實元素那樣去綁定相應的view model內的值。

完整的案例:

<select data-bind="foreach: myItems">
  <option>Item <span data-bind="text: name"></span></option>
</select>

<select data-bind="foreach: myItems">
    <option>Item <!--ko text: name--><!--/ko--></option>
</select>

<script type="text/javascript">
    var vm = {
        myItems: [
            { name: 'Item 1', id: 1},
            { name: 'Item 3', id: 3},
            { name: 'Item 4', id: 4}
        ]
    };
    ko.applyBindings(vm);
</script>

html

Html binding其實與text binding相似,只不過它的參數通常是帶有html標籤的,這樣就能夠自定義想要綁定的html元素。

下面是個很簡單的例子:

var myViewModel = {
  myHtml: ko.observable(),
}

ko.applyBindings(myViewModel);

myViewModel.myHtml("<a href='http://www.google.com'>Google</a>");

html

<p>My html element is: <span data-bind="html: myHtml"></span></p>

class與css

class綁定

<div data-bind="class: profitStatus">
          Profit Information
       </div>

    <script type="text/javascript">
      var viewModel = {
          currentProfit: ko.observable(150000)  //<div data-bind="class: profitStatus" class="profitPositive"> 
      };
   
      // Evalutes to a positive value, so initially we apply the "profitPositive" class
      viewModel.profitStatus = ko.pureComputed(function() {
          return this.currentProfit() < 0 ? "profitWarning" : "profitPositive";
      }, viewModel);
   
      // Causes the "profitPositive" class to be removed and "profitWarning" class to be added
      viewModel.currentProfit(-50);  //<div data-bind="class: profitStatus" class="profitWarning"> 
      ko.applyBindings(viewModel);
    </script>

改變的是class的值。

靜態類

CSS binding主要用於根據view model的修改來更改UI中相應元素的class,從而依照CSS文件中已經定義好的樣式來體如今頁面中。一個簡單的static css binding例子以下:

<style>
      .redText {
       color: red;
      }
    </style>
  </head>
  <body>
    <p data-bind="css: { redText: myTest() > 0 }">Test for css binding</p>

    <script type="text/javascript">
      var myViewModel = {
        myTest: ko.observable()
      };
      myViewModel.myTest(20);
      console.info(myViewModel.myTest());
      ko.applyBindings(myViewModel);
    </script>

動態類

另外,咱們也能夠經過綁定一個computed observable來動態指定css class的值,這樣的綁定稱爲dynamic css binding,簡單的例子以下:

<style>
     .redText {
       color: red;
     }

     .blueText {
       color: blue;
     }
   </style>

   <p id="redText" data-bind="css: myComputed">This is red text.</p>
   <p id="blueText" data-bind="css: myComputed">This is blue text.</p>

   <script type="text/javascript">
     var myViewModel1 = {
       myTest: ko.observable(),
       myComputed: ko.pureComputed(function() {
         return myViewModel1.myTest() > 0 ? "redText" : "blueText";
       })
     };

     var myViewModel2 = {
       myTest: ko.observable(),
       myComputed: ko.pureComputed(function() {
         return myViewModel2.myTest() > 0 ? "redText" : "blueText";
       })
     };

     ko.applyBindings(myViewModel1, document.getElementById("redText"));
     ko.applyBindings(myViewModel2, document.getElementById("blueText"));

     myViewModel1.myTest(20);
     myViewModel2.myTest(-20);
   </script>

靜態類綁定多個class

css bidning是十分靈活的,對於static css binding,咱們通常是以data-bind="css: {cssClass: viewModelProperty}"的形式來綁定css class,cssClass會根據viewModelProperty返回的值是 true 仍是 false 來決定這個class如今是否須要使用。另外,咱們也能夠一次性設置多個css classes,簡單的示例以下:

<style>
      .redText {
        color: red;
      }

      .textDecoration {
        text-decoration: underline;
      }
    </style>

    <p
      data-bind="css: {redText: redTextDecision, textDecoration: textDecorationDecision}"
    >
      This is red text, and its text-decoration is underline.
    </p>

    <script type="text/javascript">
      var myViewModel = {
        redTextDecision: ko.observable(),
        textDecorationDecision: ko.observable()
      };

      ko.applyBindings(myViewModel);

      myViewModel.redTextDecision(true);
      myViewModel.textDecorationDecision(true);
    </script>

在上例中,咱們是使用兩個view model的property來決定兩個不一樣的css class,KO也容許咱們使用一個view model property來決定多個css class,可將上例的html部分改爲以下形式:

<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,以後再也不更新。

動態類綁定多個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以空格分開並統一以字符串的方式返回便可。一個簡單的例子以下:

<style>
      .redText {
        color: red;
      }

      .textDecoration {
        text-decoration: underline;
      }
    </style>

    <p data-bind="css: textDecorationDecision">
      This is red text, and its text-decoration is underline.
    </p>

    <script type="text/javascript">
      var myViewModel = {
        textDecorationDecision: ko.observable("textDecoration redText")
      };

      ko.applyBindings(myViewModel);
    </script>

備註: 應用名稱不是合法的 javascript 變量名的 css 類

對於某些帶有特殊符號的css class,好比red-text,咱們不能直接在data-bind中以data-bind="css: {red-text: redTextDecision}"的方式來設定,而是應該在這類css class外添加一對引號使其成爲字符串常量,變成這樣:data-bind="css: {'red-text': redTextDecision}"。

若是你想套用 CSS 類my-class你 ,不能這樣寫 :

<div data-bind="css: { my-class: someValue }">...</div>

由於個人類在這一點上不是一個合法的標識符名稱。解決方案很簡單: 只需用引號包裝標識符名稱, 使其成爲字符串文本, 這在 javascript 對象文本中是合法的。例如,

<div data-bind="css: { 'my-class': someValue }">...</div>

style

style binding是與css binding不一樣的控制頁面樣式的方式,css binding須要依賴css文件中對應的樣式表,藉由增長或刪除css class來改變樣式,而style binding則是直接在相應的元素上添加或刪除style來改變頁面的樣式。一個簡單的例子以下:

<p data-bind="style: {color: redTextDecision}">This is red text.</p>

    <script type="text/javascript">
      var myViewModel = {
        redTextDecision: ko.observable("red")
      };

      ko.applyBindings(myViewModel);
    </script>

與css binding相似,咱們也能夠一次性設定多個style,以下:

<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",其餘相似的情形以此類推。

Don’t write { font-weight: someValue }; do write { fontWeight: someValue }
Don’t write { text-decoration: someValue }; do write { textDecoration: someValue }

attr

attr binding用於綁定某些元素的attribute,好比說a元素的title、href,img元素的src等。一個簡單的例子以下:

<a data-bind="attr :{ href: url, title: description}">Google's website</a>
    <img style="width: 100px; height: 100px" data-bind="attr: {src: imgUrl}"  />
    <script type="text/javascript">
      var myViewModel = {
        url: ko.observable("http://www.google.com"),
        description: ko.observable("This is google's website"),
        imgUrl: ko.observable("http://i1.sinaimg.cn/dy/deco/2013/0329/logo/LOGO_1x.png")
      };

      ko.applyBindings(myViewModel);
    </script>

若是綁定的viewModelProperty是一個observable,則每次observable改變時,UI均會更新相應的attribute;不然,UI只會設定一次attribute,以後再也不更新。

當attribute name中帶有連字符號時,咱們只需在其外部添加一對引號便可。

參考:

CharlieYuki,KnockoutJs學習筆記(五)

相關文章
相關標籤/搜索