zoukankan      html  css  js  c++  java
  • KnockOut 绑定之foreach绑定

    foreach绑定对于数组中的每一个元素复制一节标记语言,也就是html,并且将这节标记语言和数组里面的每一个元素绑定。当我们呈现一组list数据,或者一个表格的时候,十分有用。

    如果你绑定的数组是一个"监控数组" ,observable array,(和wpf里面的ObservableCollection<T>差不多)。当你添加或移除,或者重新排序数组里面的元素的时候,会动态的更新UI界面。并且此时并不会影响原先的DOM元素。这样比我们直接重新生成一个数组并且绑定元素高效的多。

    当然,foreach也支持嵌套绑定,或者和其他工作流绑定例如if 或者with。

    Example 1: 迭代绑定一个数组

    对数组中的每一个元素生成一行数据的只读表。

    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/knockout-3.2.0.js"></script>
    
    <table>
        <thead>
            <tr><th>First name</th><th>Last name</th></tr>
        </thead>
        <tbody data-bind="foreach: people">
            <tr>
                <td data-bind="text: firstName"></td>
                <td data-bind="text: lastName"></td>
            </tr>
        </tbody>
    </table>
    
    <script type="text/javascript">
        ko.applyBindings({
            people: [
                { firstName: 'Bert', lastName: 'Bertington' },
                { firstName: 'Charles', lastName: 'Charlesforth' },
                { firstName: 'Denise', lastName: 'Dentiste' }
            ]
        });
    </script>

    Example 2: 给例1中的制度表加上一个增加和移除方法

    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/knockout-3.2.0.js"></script>
    
    <h4>People</h4>
    <ul data-bind="foreach: people">
        <li>
            Name at position <span data-bind="text: $index"> </span>:
            <span data-bind="text: name"> </span>
            <a href="#" data-bind="click: $parent.removePerson">Remove</a>
        </li>
    </ul>
    <button data-bind="click: addPerson">Add</button>
    
    <script type="text/javascript">
        function AppViewModel() {
            var self = this;
    
            self.people = ko.observableArray([
                { name: 'Bert' },
                { name: 'Charles' },
                { name: 'Denise' }
            ]);
    
            self.addPerson = function () {
                self.people.push({ name: "New at " + new Date() });
            };
    
            self.removePerson = function () {
                self.people.remove(this);
            }
        }
    
        ko.applyBindings(new AppViewModel());
    </script>

    要点1:  用 $data来指向数组的每一条数据

    就像在上面的例子中展示的。foreach绑定能够指向数组每一条数据的属性。例如例1中的firstName 和lastName.但是,如果我们想指向数组本身,应该怎么办,此时我们可以用$.data.在foreach绑定中,$data指的就是数组的当前的元素项。

    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/knockout-3.2.0.js"></script>
    <ul data-bind="foreach: months">
        <li>
            The current item is: <b data-bind="text: $data"></b>
        </li>
    </ul>
    
    <script type="text/javascript">
        ko.applyBindings({
            months: ['Jan', 'Feb', 'Mar', 'etc']
        });
    </script>

     当然,如果你非要这样做的话, 你也可以给你指向的每一个属性加上一个 $data前缀.例如,你也可以在例1中像下面这样写,虽然这样写没必要,因为它的默认上下文就是$data:

    <td data-bind="text: $data.firstName"></td>

    要点 2: 使用$index, $parent, 和其他的上下文属性

    就像我们在例2 中看到的那样。你可一用$index 来表示数组中当前项从零开始的索引。 $index是一个监控属性,当数组的项变更的时候$index也会自动更新。

    同样,你也可以用$parent来指向foreach外的数据。如果foreach对应的是viewmodel的直接子元素,那么$parent就是指的viewmodel,$root是对应根元素,多层循环嵌套的时候使用$root

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

    要点 3: 用as 给foreach项赋值一个别名

    就想在要点1里面描述的那样。我们可以引用每一个数组项用  $data 上下文变量。但在一些特殊情况下,给当前项一个别名用起来更方便。尤其在多层嵌套结构中:

    别名使用的语法如下:

    <ul data-bind="foreach: { data: people, as: 'person' }"></ul>

    现在在foreach循环的任何地方,绑定都可以根据person指向当前people的数组项。这种语法在多层foreach嵌套的场景中非常有用。例如:

    <ul data-bind="foreach: { data: categories, as: 'category' }">
        <li>
            <ul data-bind="foreach: { data: items, as: 'item' }">
                <li>
                    <span data-bind="text: category.name"></span>:
                    <span data-bind="text: item"></span>
                </li>
            </ul>
        </li>
    </ul>
     
    <script>
        var viewModel = {
            categories: ko.observableArray([
                { name: 'Fruit', items: [ 'Apple', 'Orange', 'Banana' ] },
                { name: 'Vegetables', items: [ 'Celery', 'Corn', 'Spinach' ] }
            ])
        };
        ko.applyBindings(viewModel);
    </script>

    注意: 记得通过as给别名 赋值的时候,传过去一个字符串'category'不是as: category), 因为我们是要给变量起一个别名,而不是传递一个标识符变量过去。

    Note 4: 没有一个容器元素的时候使用foreach

    在一些情况下,你想要通过foreach绑定一段标记语言html,但是没有供foreach绑定的元素。例如下面这张情景:

    <ul>
        <li class="header">Header item</li>
        <!-- The following are generated dynamically from an array -->
        <li>Item A</li>
        <li>Item B</li>
        <li>Item C</li>
    </ul>

    这种情况下没有任何元素可供foreach绑定。你不能放到ul里面,因为这时候会把header也放到复制的循环里面去。你也不能放其它的元素在ul里面,因为ul里面只允许放<li>元素。

    要想处理这种情况。我们可以用无容器绑定语法。这中情况是依赖于html的注释标签。如下:

    <ul>
        <li class="header">Header item</li>
        <!-- ko foreach: myItems -->
            <li>Item <span data-bind="text: $data"></span></li>
        <!-- /ko -->
    </ul>
     
    <script type="text/javascript">
        ko.applyBindings({
            myItems: [ 'A', 'B', 'C' ]
        });
    </script>

    <!-- ko --> 和 <!-- /ko --> 注释作为标签的开始和结束,定义了一个虚元素来包含我们需要重复引用的标记语言在里面,knockout理解这种虚元素语法。我们可以就当真的有一个html元素来使用它。

  • 相关阅读:
    最小生成树
    BZOJ3894:文理分科(最大流)(同BZoj3438)
    BZOJ3438:小M的作物 (最大闭合权图->最小割)
    BZOJ 1305:dance跳舞(二分+最大流)
    BZOJ1266:上学路线route (最短路+最小割)
    BZOJ1854:游戏(二分图匹配)
    【PowerOJ1738】最小路径覆盖
    【SPOJ839】Optimal Marks 网络流
    【USACO】AC自动机
    【国家集训队2011】聪聪可可 树分治
  • 原文地址:https://www.cnblogs.com/gavinjay/p/10768378.html
Copyright © 2011-2022 走看看