2012年8月25日 星期六

knockoutjs 17 if binding

knockoutjs if binding
example1:
<!DOCTYPE html>
<html>
<head>
<title>if binding example</title>
<meta charset="UTF-8"/>
<script src="../lib/jquery-1.7.1.min.js"></script>
<script src="../lib/knockout-2.1.0.js"></script>
<script>
$(document).ready(function(){
ko.applyBindings({displayMessage: ko.observable(false)});
});
</script>
</head>
<body>
<!--if binding,當displayMessage為true時,其DIV內容文字顯現-->

<div data-bind="if: displayMessage">Here is a message. Astonishing.</div>
<input type="checkbox" data-bind="checked: displayMessage" /> Display message
</body>
</html>

說明:
hide (displayMessage value is false):   
   <body>
   <div data-bind="if: displayMessage"></div>
   <input type="checkbox" data-bind="checked: displayMessage"> Display message
   </body>
  • note:注意div內容將為空,div依然存在於DOM中,但內容文字不會存在,如果是visible bind即使處在hide但其內容文字依然存在於DOM中。
show (displayMessage value is true):
  <body>
  <div data-bind="if: displayMessage">Here is a message. Astonishing.</div>
  <input type="checkbox" data-bind="checked: displayMessage"> Display message
  </body>

  • if binding 會直接對DOM elements 的內容操作,會直接將內容移除。
  • visible是使用CSS display:none 來隱藏,visible的隱藏DOM elements中的內容依然會存在。

example 2:

<!DOCTYPE html>
<html>
<title>if binding example</title>
<meta charset="UTF-8"/>
<script src="../lib/knockout-2.1.0.js"></script>
</head>
<body>
    <div data-bind="if: show">Here is a message. 一</div>
    <div data-bind="if: hide">Here is a message. 二</div>
    <div data-bind="if: show">Here is a message. 三</div>
    <script>
       function ViewModle() {
           this.show = ko.observable(true);
           this.hide = ko.observable(false);
       }
       ko.applyBindings(new ViewModle());
    </script>
</body>
</html><head>

結果:

Here is a message. 一
Here is a message. 三

example3:
<!DOCTYPE html>
<html>
<head>
<title>if Binding</title>
<meta charset="UTF-8"/>
<script src="../lib/jquery-1.7.1.min.js"></script>
<script src="../lib/knockout-2.1.0.js"></script>
<script>
$(document).ready(function(){
    function ViewModel(){
   this.planets = [
            {name: 'Mercury', capital: null },
            {name: 'Earth', capital: { cityName: 'Barnsley' }}
]; 
}
ko.applyBindings(new ViewModel());
});
</script>
</head>
<body> <!--這裡使用foreach binding,將與ViewModel中的planets繫結,
    將會迭代planets陣列,依其長度重複ul中的內容結構-->

<ul data-bind="foreach: planets">
    <li>
        <!--這裡使用text binding,將與ViewModel中的name繫結-->
        Planet: <b data-bind="text: name"></b>
        <!--這裡使用if binding,將與ViewModel中的 capital 繫結-->
        <div data-bind="if: capital">        <!--這裡使用text binding,因為父層DIV沒有使用with繫結,所以要依物件結構呼叫繫結目標-->
            Capital: <b data-bind="text: capital.cityName"></b>
        </div>
    </li>
</ul>
</body>
</html>

結果:
  • Planet: Mercury
  • Planet: Earth
    Capital: Barnsley
HTML 原始碼內容: 

<body>
<ul data-bind="foreach: planets">
    <li>
        Planet: <b data-bind="text: name">Mercury</b>
        <div data-bind="if: capital"></div>  <-DOM存在,其內容文字不存在。
    </li>

    <li>
        Planet: <b data-bind="text: name">Earth</b>
        <div data-bind="if: capital">                                  
            Capital: <b data-bind="text: capital.cityName">Barnsley</b>
        </div>                                                         
    </li>
</ul>
</body>

note: if bind的繫結屬性若為nullundefined0則都視為false.


example4 使用xml 註解方式操作 if bind:
  • 注意程式碼中紅色註解為knockoutjs框架中所使用的xml註解宣告binding。
<!DOCTYPE html>
<html>
<head>
<title>if Binding</title>
<meta charset="UTF-8"/>     
<script src="../lib/jquery-1.7.1.min.js"></script>
<script src="../lib/knockout-2.1.0.js"></script>
<script>            
$(document).ready(function(){   
    function ViewModel(){
        this.planets = [
            {name: 'Mercury', capital: null },
            {name: 'Earth', capital: { cityName: 'Barnsley' }}
        ]; 
    }                       
    ko.applyBindings(new ViewModel());
}); 
</script>
</head>
<body>      
<ul data-bind="foreach: planets">
    <li>
        Planet: <b data-bind="text: name"></b>
         <!-- ko if: capital -->
        <div>
            Capital: <b data-bind="text: capital.cityName"></b>
        </div>
        <!-- /ko -->
    </li>
</ul>   
</body>
</html>

結果:
  • Planet: Mercury
  • Planet: Earth
  • Capital: Barnsley
輸出畫面上雖然看起來一樣但是,若使用chrome檢查原素可見如下:

 HTML 原始碼內容:

  • 使用註解標籤方式的if binding 整各DOM elements會是不存在的。


<body>      
<ul data-bind="foreach: planets">
    <li>
        Planet: <b data-bind="text: name">Mercury</b>
         <!-- ko if: capital --><!-- /ko -->  <-注意DIV將不存在,陣列中第一筆capital為null。
    </li>

    <li>
        Planet: <b data-bind="text: name">Earth</b>
        <!-- ko if: capital --> <-內容生成,因為陣列中第二筆資料的capital存在。
        <div>                                                          
            Capital: <b data-bind="text: capital.cityName">Barnsley</b>
        </div>                                                         
        <!-- /ko -->
    </li>
</ul>
</body>

knockoutjs 16 foreach binding

knockoutjs foreach binding
Example1:

<!DOCTYPE html>
<html>
<head>
<title>foreach binding example</title>
<meta charset="UTF-8"/>
<style type="text/css">
table, td, th{
border:1px solid green;
}
th{
background-color:green;
color:white;
}
td{
color:#DD8822;
/**上右下左*/
padding: 6px 8px 6px 8px;
}
</style>
<script src="../lib/knockout-2.1.0.js"></script>
</head>
<body>
<table>
    <thead>
        <tr><th>書名</th><th>售價</th></tr>
    </thead>
    <tbody data-bind="foreach: dataProvider">
        <tr>
            <td data-bind="text: name"></td>
            <td data-bind="text: price"></td>
        </tr>
    </tbody>
</table>
<script>
(function(window, undefined){   
var ko = window.ko,
    viewModel={       
        dataProvider:[                                            
            { name: '驚缸郎前傳', price: 399 },
            { name: '雷神反核電', price: 299 },
            { name: '缸帖人怕觸電', price: 299 },  
            { name: '綠巨人好客的煩惱', price: 399 },
            { name: '台灣隊長的內心世界', price: 299 },
            { name: '黑寡婦:我只是不小心把蜘蛛人吃了', price: 299 }
        ]   
    };
//設定viewModel與DOM bind
ko.applyBindings(viewModel);
})(window);    
</script>
</body>
</html>

輸出結果:


書名售價
驚缸郎前傳 399
雷神反核電 299
缸帖人怕觸電 299
綠巨人好客的煩惱 399
台灣隊長的內心世界 299
黑寡婦:我只是不小心把蜘蛛人吃了 299

Example 2.
<!DOCTYPE html>
<html>
<head>
<title>foreach binding example</title>
<meta charset="UTF-8"/>
<style type="text/css">
</style>
<script src="../lib/knockout-2.1.0.js"></script>
</head>
<body>
<h4>明星</h4>
<!--foreach binding-->
<ul data-bind="foreach: dataProvider">
    <!--該區塊將會依資料長度重複產生-->
    <li>
        陣列中位置  <span data-bind= " text: $index"> </span>:
        <span data-bind="text: name"> </span>
        <a href="#" data-bind="click: $parent.removePerson">Remove</a>
    </li>
</ul>
<!--click binding-->
<button data-bind="click: addPerson">Add</button>
<script>
(function(window, undefined){
    function AppViewModel(){
        var self = this;
        self.dataProvider = ko.observableArray(null);
        
        //加一個項目 (add item)
        self.addPerson = function() {
            self.dataProvider.push({ name: "New at " + new Date() });
        };
     
        //移除一個項目  (remove item)
        self.removePerson = function() {
            self.dataProvider.remove(this);
        }
    }
    var viewModel = new AppViewModel(); 
    //bind viewModel   
    ko.applyBindings(viewModel);    
    //假裝是remote取回的遠端資料
    var result=[
            { name: '卡 卡' },
            { name: '艾薇兒' },
            { name: '丹尼爾' }
        ];
    //將值設定給viewMode裡的dataProvider屬性,屬性變動對應bind的UI將會自動改變內容。
    viewModel.dataProvider(result);    
})(window);   
</script>
</body>
</html>


Example 3:
<!DOCTYPE html>
<html>
<head>
<title>foreach binding example</title>
<meta charset="UTF-8"/>
<script src="../lib/knockout-2.1.0.js"></script>
</head>
<body>
<ul data-bind="foreach: myData">
    <li>
        <span>當前項目:  </span><b data-bind="text: $data"></b>
    </li>
</ul>
<script>
var myViewModel
{
    myData: [ '一月', '二月', '三月', '四月' ]
};

ko.applyBindings(myViewModel); 
</script>
</body>
</html>


Example4: (具有afterRender的foreach,在元素產生後所要對DOM元素所做的宣染動作)


<!DOCTYPE html>
<html>
<head>
<title>foreach binding example</title>
<meta charset="UTF-8"/>
<style type="text/css">
</style>
<script src="../lib/jquery-1.7.1.min.js"></script>
<script src="../lib/knockout-2.1.0.js"></script>
<script>
$(document).ready(function(){
var viewModel={
        myItems: ko.observableArray([ 'A', 'B', 'C' ]),
handleAfterRender: function(elements, data) {   
         $(elements).css({ color: 'red' });
}
};     
     ko.applyBindings(viewModel);
});  
</script>
</head>
<body>
<ul data-bind="foreach: { data: myItems, afterRender: handleAfterRender }">
    <li data-bind="text: $data"></li>
    <span></span>
    <div></div>    
</ul>
</body>
</html>