• Knockoutjs属性绑定(Bindings)之流程控制(Control flow)


    在上一篇《Knockoutjs属性绑定(Bindings)之控制文本和外观(Controlling text and appearance)》我们介绍了怎么样为View层的组件绑定对应的属性,这篇文章我们接着介绍Knockoutjs的属性绑定,这次我们主要介绍的是怎么样通过Knockoutjs来控制组件的流程显示(比如循环、判断是否显示等)。

    一、foreach binding

    使用此功能可以方便我们循环遍历输出某个数组、集合中的内容。

    (1)、循环遍历输出数组

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <table> 
     4     <thead> 
     5         <tr><th>First name</th><th>Last name</th></tr> 
     6     </thead> 
     7     <tbody data-bind="foreach: people"> 
     8         <tr> 
     9             <td data-bind="text: firstName"></td> 
    10             <td data-bind="text: lastName"></td> 
    11         </tr> 
    12     </tbody> 
    13 </table> 
    14   
    15 <script type="text/javascript">
    16     ko.applyBindings({
    17         people: [
    18             { firstName: 'Bert', lastName: 'Bertington' },
    19             { firstName: 'Charles', lastName: 'Charlesforth' },
    20             { firstName: 'Denise', lastName: 'Dentiste' }
    21         ]
    22     });
    23 </script>

    (2)、动态增加和删除遍历节点

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <h4>People</h4> 
     4 <ul data-bind="foreach: people"> 
     5     <li> 
     6         Name at position <span data-bind="text: $index"> </span>: 
     7         <span data-bind="text: name"> </span> 
     8         <a href="#" data-bind="click: $parent.removePerson">Remove</a> 
     9     </li> 
    10 </ul> 
    11 <button data-bind="click: addPerson">Add</button>
    12   
    13 <script type="text/javascript">
    14     function AppViewModel() {
    15         var self = this;
    16 
    17         self.people = ko.observableArray([
    18         { name: 'Bert' },
    19         { name: 'Charles' },
    20         { name: 'Denise' }
    21     ]);
    22 
    23         self.addPerson = function () {
    24             self.people.push({ name: "New at " + new Date() });
    25         };
    26 
    27         self.removePerson = function () {
    28             self.people.remove(this);
    29         }
    30     }
    31 
    32     ko.applyBindings(new AppViewModel());
    33 </script>

    (3)、如果我们想要输出数组中的所有元素而不是像例一中使用firstName去指定元素的话,我们可以使用$data来进行输出。比如:

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <ul data-bind="foreach: months"> 
     4     <li> 
     5         The current item is: <b data-bind="text: $data"></b> 
     6     </li> 
     7 </ul> 
     8   
     9 <script type="text/javascript">
    10     ko.applyBindings({
    11         months: ['Jan', 'Feb', 'Mar', 'etc']
    12     }); 
    13 </script>

    当然,我们也可以使用$data来调用数组中具体的元素,比如我们要使用$data调用例1中的firstName的话,我们可以使用$data.firstName来输出firstName。
    (4)、使用$index、$parent等其他的上下文属性

    我们曾在例2中使用了$index来表示我们数组的下标,$index是Knockoutjs为我们提供的属性,我们可以直接引用,它会随着数组等下标的变化动态变化的,比如如果数组的长度减少了1,$index的值也会跟着减少的。

    我们也可以使用$parent来使用foreach元素之外的属性,比如:

    1 <h1 data-bind="text: blogPostTitle"></h1> 
    2 <ul data-bind="foreach: likes"> 
    3     <li> 
    4         <b data-bind="text: name"></b> likes the blog post <b data-bind="text: $parent.blogPostTitle"></b> 
    5     </li> 
    6 </ul>

    这里使用$parent来调用foreach循环体之外的blogPostTitle属性。
    (5)、使用"as"为foreach中的元素定义别名

    我们可以使用$data来代替数组中的元素,同时我们也可以使用as来为我们要遍历的元素起一个别名。

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <ul data-bind="foreach: { data: categories, as: 'category' }"> 
     4     <li> 
     5         <ul data-bind="foreach: { data: items, as: 'item' }"> 
     6             <li> 
     7                 <span data-bind="text: category.name"></span>: 
     8                 <span data-bind="text: item"></span> 
     9             </li> 
    10         </ul> 
    11     </li> 
    12 </ul> 
    13   
    14 <script>
    15     var viewModel = {
    16         categories: ko.observableArray([
    17             { name: 'Fruit', items: ['Apple', 'Orange', 'Banana'] },
    18             { name: 'Vegetables', items: ['Celery', 'Corn', 'Spinach'] }
    19         ])
    20     };
    21     ko.applyBindings(viewModel); 
    22 </script>

    在使用的时候我们要注意,起别名使用的是as:'category'而不是as:category。

    (6)、在没有绑定属性的情况下使用foreach

    有的时候我们想要循环输出一些特殊的内容,比如我们想要输入下面文本中的<li></li>标签:

    1 <ul> 
    2     <li class="header">Header item</li> 
    3     <!-- The following are generated dynamically from an array --> 
    4     <li>Item A</li> 
    5     <li>Item B</li> 
    6     <li>Item C</li> 
    7 </ul>

    如果我们想要循环输出上面代码中的<li></li>标签的话,我们就没有一个可以绑定foreach的元素,此时我们可以通过以下的代码来实现:

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <ul> 
     4     <li class="header">Header item</li> 
     5     <!-- ko foreach: myItems --> 
     6         <li>Item <span data-bind="text: $data"></span></li> 
     7     <!-- /ko --> 
     8 </ul> 
     9   
    10 <script type="text/javascript">
    11     ko.applyBindings({
    12         myItems: ['A', 'B', 'C']
    13     }); 
    14 </script>

    我们使用<!--ko--><!--/ko-->来表示循环的开始和结束,这是一个虚拟的标签,Knockoutjs能够对其中的foreach进行绑定就好像你将foreach绑定到了一个真实的标签上一样。

    (7)、默认不显示被标示为删除的元素

    有的时候我们要跳过数组中的一些元素,此时这些元素已经被标示为删除,但并没有被真实删除,这些元素当我们使用foreach输出的时候是默认不显示的,如果我们想要这些元素显示的话,我们可以使用includeDestroyed这个选项,比如:

    1 <div data-bind='foreach: { data: myArray, includeDestroyed: true }'> 
    2     ... 
    3 </div>


    二、if binding  和 if not binding

    (1)、使用if binding可以控制某个组件动态显示,类似我们之前接触到的visible属性,不过此属性绑定过以后就不能更改,而if binding可以根据相应的条件控制组件是否显示,下面是一个简单的例子:

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <label><input type="checkbox" data-bind="checked: displayMessage" /> Display message</label> 
     4   
     5 <div data-bind="if: displayMessage">Here is a message. Astonishing.</div>
     6   
     7 <script type="text/javascript">
     8     ko.applyBindings({
     9         displayMessage: ko.observable(false)
    10     });
    11 </script>

    此例根据checkbox是否勾选来控制是否显示下面的一个<div>。
    我们也可以使用if来判断某个元素是否为null,如果为null则不会显示,如下:

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <ul data-bind="foreach: planets"> 
     4     <li> 
     5         Planet: <b data-bind="text: name"> </b> 
     6         <div data-bind="if: capital"> 
     7             Capital: <b data-bind="text: capital.cityName"> </b> 
     8         </div> 
     9     </li> 
    10 </ul> 
    11   
    12   
    13 <script>
    14     ko.applyBindings({
    15         planets: [
    16             { name: 'Mercury', capital: null },
    17             { name: 'Earth', capital: { cityName: 'Barnsley'} }
    18         ]
    19     }); 
    20 </script>

    此例中如果capital为null,则不会进行显示。此时,如果没有if进行判断的话,则在使用capital.cityName时就会出错。
    (2)、if not binding的使用方法和if binding的使用方法一样,这里就不作介绍了。

    三、with binding

    我们可以使用with binding来重新定义一个上下文绑定,比如:

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <h1 data-bind="text: city"> </h1> 
     4 <p data-bind="with: coords"> 
     5     Latitude: <span data-bind="text: latitude"> </span>, 
     6     Longitude: <span data-bind="text: longitude"> </span> 
     7 </p> 
     8   
     9 <script type="text/javascript">
    10     ko.applyBindings({
    11         city: "London",
    12         coords: {
    13             latitude: 51.5001524,
    14             longitude: -0.1262362
    15         }
    16     }); 
    17 </script>

    这样我们在使用coords下的latitude和longitude的时候我们就不需要使用coords.latitude来调用了,因为我们使用with:coords来指定了coords的上下文,当我们使用coords下面的属性时就可以直接使用了。
    下面提供一个动态交互的例子:

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 <form data-bind="submit: getTweets"> 
     4     Twitter account: 
     5     <input data-bind="value: twitterName" /> 
     6     <button type="submit">Get tweets</button> 
     7 </form> 
     8   
     9 <div data-bind="with: resultData"> 
    10     <h3>Recent tweets fetched at <span data-bind="text: retrievalDate"> </span></h3> 
    11     <ol data-bind="foreach: topTweets"> 
    12         <li data-bind="text: text"></li> 
    13     </ol> 
    14   
    15     <button data-bind="click: $parent.clearResults">Clear tweets</button> 
    16 </div>
    17   
    18 <script type="text/javascript">
    19     function AppViewModel() {
    20         var self = this;
    21         self.twitterName = ko.observable('@StephenFry');
    22         self.resultData = ko.observable(); // No initial value 
    23 
    24         self.getTweets = function () {
    25             twitterApi.getTweetsForUser(self.twitterName(), function (data) {
    26                 self.resultData({
    27                     retrievalDate: new Date(),
    28                     topTweets: data.slice(0, 5)
    29                 });
    30             });
    31         }
    32 
    33         self.clearResults = function () {
    34             self.resultData(undefined);
    35         }
    36     }
    37 
    38     ko.applyBindings(new AppViewModel()); 
    39 </script>

    以上就是流程控制的全部内容。

  • 相关阅读:
    HDOJ/HDU 2352 Verdis Quo(罗马数字与10进制数的转换)
    HDOJ/HDU 2203 亲和串(简单的判断~Java的indexOf()方法秒)
    HDOJ/HDU 2163 Palindromes(判断回文串~)
    js之函数
    js琐碎知识点
    position
    css属性background
    图片展示失效容错处理
    文字打点
    浮动的一些知识点
  • 原文地址:https://www.cnblogs.com/wukong65/p/2794628.html
Copyright © 2020-2023  润新知