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元素来使用它。

给TA打赏
共{{data.count}}人
人已打赏
随笔日记

android渠道打包怎样实现最方便

2020-11-9 4:35:27

随笔日记

asp.net core系列 60 Ocelot 构建服务认证示例

2020-11-9 4:35:29

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索