knockoutJS学习笔记06:ko数组与模板绑定

  前面已经介绍了基本的绑定和模板相关知识,接下来就看ko里的数组和模板绑定,数组和模板绑定应该是实际项目中用得比较多的,ko提供了很好的支持。

一、observaleArray

  前面的监控属性都是单个对象,用的是ko.observable;有时候后台返回的是一个列表,也就是数组,这个时候就需要用监控数组了。监控数组与监控属性几乎一样,只不过它是一个数组对象,拥有数组的特点。例如:创建一个简单的监控数组:

  var arr = ko.observableArray();

  也可以开始就进行初始化:  

  arr = ko.observableArray([1,2,3]);

  普通数组获取长度就是 arr.length,而监控数组与监控属性一样,需要用方法,例如:arr().length。

二、监控数组常见方法

  监控数组拥有普通数组的所有方法,用法也基本一样。

  2.1 push 增加一个新元素

    arr.push(4);  

  2.2 pop 删除一个元素,并返回这个元素

    var v = arr.pop();

  2.3 shift 在开始处删除一个元素,并返回这个元素

    var v = arr.shift();

  2.4 unshift 在开始处增加一个元素

    arr.unshift(0);

  2.5 reverse 反转数组

    arr.reverse();

  2.6 sort 数组排序

    arr.sort();

  可以看到,上面的方法和js里的数组方法一模一样,用法也是一样的。此外,ko还支持另外两个方法,remove 和 removeAll:

    remove:移除指定元素或移除指定条件的元素。如:arr.remove(1); 或者 arr.remove(function(item){return item > 1;});

    removeAll:移除指定的元素集或移除所有元素。如:arr.removeAll([1,2]); 或者 arr.removeAll();

  上面数组的内容只是简单的数据类型,实际也可以复杂的类型。需要注意的是,为了提高性能,监控数组只监控数组对象,而不监控数组元素对象的属性。也就是说,如果arr元素是对象,那么对arr进行的操作会反应到UI(反之也会);但对arr[0]对象内部的属性的操作,就不会反应到UI(反之也不会)。

二、foreach 绑定

  既然是数组,自然就需要遍历输出了。foreach 绑定就是用来遍历集合的,如果集合是空的,会在页面上留下一个空的模板。

  2.1 foreach指定要遍历的属性,内部的结构会自动循环绑定。例如:

    <div data-bind="foreach:list">
        <p>姓名:<span data-bind="text:name"></span>,年龄:<span data-bind="text:age"></span></p>
    </div>

  2.2 通过 as 关键字为遍历的属性定义别名,这样就可以通过别名对它进行访问。

    <ul data-bind="foreach:{data:data,as:‘data‘}">
        <li>
            <p data-bind="text:name"></p>
            <ul data-bind="foreach:{data:contains,as:‘item‘}">
                <li>
                    <p><span data-bind="text:item.name"></span>属于<span data-bind="text:data.name"></span></p>
                </li>
            </ul>
        </li>
    </ul>
    var data = [
        {name:"水果",contains:[{name:"苹果",work:"苹果的作用"},{name:"香蕉",work:"香蕉的作用"}]},
        {name:"蔬菜",contains:[{name:"青菜",work:"青菜的作用"},{name:"白菜",word:"白菜的作用"}]}
    ];
    ko.applyBindings(data);

  这里要注意,as后面的名称必须加引号。在ko里,凡是作为名称的,都必须加引号,而如果作为对象或者属性的,就不需要。

三、ko 模板绑定

  ko 的模板用template指定,template 可以直接指定模板名称,也支持更多选项。

  3.1 直接指定模板名称

<div data-bind="template:‘tmpl‘"></div>

  3.2 templdate 支持更多的选项,让我们可以更灵活的控制整个渲染过程。

    name(必选项) — 需要render的模板ID。

    data(可选项) — 需要render到模板的数据。如果你忽略整个参数,KO将查找foreach参数,或者是应用整个view model对象。

    foreach(可选项) — 指定KO按照“foreach”模式render模板。

    afterAdd或beforeRemove(可选项) — 在foreach模式下使用callback函数。

    templateOptions(可选项) — 在render模板的时候,传递额外数据以便使用。

<div data-bind="template:{name:‘koPersonList‘,foreach:list}"></div>
<script type="text/tmpl" id="koPersonList">
    <p>姓名:<span data-bind="text:name"></span>,年龄:<span data-bind="text:age"></span></p>
</script>

    另外,template里的name 属性不只可以写死为一个模板名称,还可以是一个方法属性,由它来动态决定使用哪个模板。例如下面的例子,在遍历的时候,会根据名称来决定使用哪个模板。   

       <div data-bind="template:{name:display,foreach:list}"></div>
        this.display = function(item){
            if(item.name() === "tom1"){
                return "tmpl1";//使用模板1渲染
            }
            return "tmpl2";//使用模板2渲染
        }

三、结合jqtmpl

  集合类型通常要进行遍历渲染,之前我们已经写过模板引擎了,也介绍了jsRender,都支持循环遍历。ko 默认支持的jqtmpl模板。简单介绍一下jqtmpl,它的 tag 有:

  ${变量} : 输出变量值

  ${{html 变量}} :输入变量html

  ${{if condition}}...${{else condition}}...${{else}}...${{/if}} :if-else 判断

  ${{each(index,item) 集合}...${{/each}} :遍历

  可以看出,jqtmpl和jsRender的结构是非常像。我们用template集合jqtmpl看两个例子。 

  例子1:

<div data-bind="template:‘person‘"></div>
<script type="text/tmpl" id="person">
    <p>姓名:${name},年龄:${age}</p>
</script>:    

  例子2:

    <div id="" data-bind="template:{name:‘personList‘,foreach:list}"></div>
    <script type="text/tmpl" id="personList">
        <p>姓名:${name},年龄:${age}</p>
    </script>
    function Person(name,age){
        this.name = name;
        this.age = age;
    }
    function ViewModel(){
        this.list = [
            new Person("tom",18),
            new Person("jack",20),
            new Person("lucy",22)];
    }
    ko.applyBindings(new ViewModel());   

  注意:和jqtmpl一起使用时,ko.js必须先引入,后再引入jqtmpl.js,否则会没有效果。

  上面的例子就是把ko的输出方式,换成jqtmpl的输出方式,结果是一样的。那么使用<span data-bind="text:someObservableValue"></span> 与 ${someObservableValue} 有什么区别呢?

  当模板内部使用data-bind属性的时候,KO是单独为这个绑定单独跟踪依赖项的。当model改变的时候,KO只会更新绑定的元素以及子元素而不需要重新render整个模板。所以如果你声明这样的代码是<span data-bind=‘text: someObservableValue‘></span>,当 someObservableValue改变的时候,KO将只是简单地更新<span>元素的text值而不需要重新render整个模板。

  不过,如果模板内部使用的observable值(例如${ someObservableValue }),如果这个observable值改变了,那KO将重新render整个模板(这往往不是我们想要的)。

  这就是说,很多情况下<span data-bind=‘text: someObservableValue‘></span>性能要比${ someObservableValue }要好,因为值改变的话不会影响临近元素的状态。不过${ someObservableValue }语法比较简洁,如果你的模板比较小的话,还是更合适的,不会带来大的性能问题。

五、用ko模板完成开篇的demo

  开篇我们用了多种方式完成一个简单的demo,这样用ko来完成相同的功能。

  html:  

    <div id="main">
        <div id="title">所有课程</div>
        <ul id="course" data-bind="template:{name:‘courseTmpl‘,foreach:courseList}"></ul>
    </div>

  模板:

<script type="text/tmpl" id="courseTmpl">
    <li>
        <a data-bind="attr:{href:‘Default.aspx?courseID=‘+CourseID}">
            <div class="course-img">
                <img data-bind="attr:{src:IconPath,alt:CourseName}"/>
            </div>
            <div class="course-info">
                <div class="names">
                    <span data-bind="text:CourseName"></span>
                    <span data-bind="text:TeacherName" class="fr"></span>
                </div>
                <div class="pros">
                    <span data-bind="text:CreatedDate"></span>
                    <span class="fr"><span data-bind="text:StudyNumber"></span>人学习</span>
                </div>
            </div>
        </a>
    </li>
</script>

  js:

    function CourseInfoVM(){
        var self = this;
        this.courseList = ko.observableArray();
    }
    var courseInfoVM = new CourseInfoVM();
    ko.applyBindings(courseInfoVM,document.getElementById("course"));
    window.Tester.callback(function(data){
          courseInfoVM.courseList(data);
    })

 六、总结

  ko的模板绑定提供了很多的功能和支持,让我们对集合类型的处理更加方便,页面的结构更加清晰,脚本更加简洁。

时间: 2024-10-06 06:17:07

knockoutJS学习笔记06:ko数组与模板绑定的相关文章

knockoutJS学习笔记08:表单域绑定

前面的绑定都是用在基本标签上,这章主要讲表单域标签的绑定. 一.value 绑定 绑定标签:input text.textarea. <p>用户名:<input type="text" data-bind="value:name" /><span data-bind="text:name"></span></p> <p>密码:<input type="text

WebApi学习笔记06:使用webapi模板--仓储模式--Unity依赖注入

1.Web项目 1.1概述 对数据操作封装使用存储模式是很常见的方式,而使用依赖注入来降低耦合度(方便创建对象,可以抛弃经典的工厂模式)…… 1.2创建项目 1.3添加模型 在Models下,添加Product.cs: namespace WebApi06.Models { public class Product { public int ID { get; set; } public string Name { get; set; } public decimal Price { get;

Swift学习笔记四:数组和字典

最近一个月都在专心做unity3d的斗地主游戏,从早到晚,最后总算是搞出来了,其中的心酸只有自己知道.最近才有功夫闲下来,还是学习学习之前的老本行--asp.net,现在用.net做项目流行MVC,而不是之前的三层,既然技术在更新,只能不断学习,以适应新的技术潮流! 创建MVC工程 1.打开Visual studio2012,新建MVC4工程 2.选择工程属性,创建MVC工程 3.生成工程的目录 App_Start:启动文件的配置信息,包括很重要的RouteConfig路由注册信息 Conten

RX学习笔记:JavaScript数组操作

RX学习笔记:JavaScript数组操作 2016-07-03 增删元素 unshift() 在数组开关添加元素 array.unshift("value"); array.unshift(123); array.unshift("value1","value2"); push() 在数组末尾添加元素 array.push("value"); array.push(123); array.push("value1&

Sharepoint2013搜索学习笔记之自定义结果显示模板(九)

搜索结果通过套用定义好的显示模板来展示结果,显示模板由js和html组成,我们可以通过修改显示模板,然后将修改好的显示模板跟搜索结果绑定起来,来修改搜索结果的显示效果,例子如下图: 修改前 修改后 第一步,确定显示需要修改的显示模板,打开ie,摁f12,定位到搜索结果列表项找到需要修改的搜索项模板 第二步,从搜索中心进入网站设置页面 第三步,点击web设计器库的母版页和页面布局 第四步,进入母版页样式库的 Display Templates/search目录,该目录就是存放搜索结果显示模板的地方

iOS学习笔记06—Category和Extension

iOS学习笔记06—Category和Extension 一.概述 类别是一种为现有的类添加新方法的方式. 利用Objective-C的动态运行时分配机制,Category提供了一种比继承(inheritance)更为简洁的方法来对class进行扩展,无需创建对象类的子类就能为现有的类添加新方法,可以为任何已经存在的class添加方法,包括那些没有源代码的类(如某些框架类). 二.示例 1.声明类别 @interface NSString (CategoryDemo) -(NSNumber*)

非计算机专业的码农C#学习笔记 五、数组和集合

数组和集合 1.数组问题Array (1)一维数组:int[] arr={1,2,3,5,5} string[] s={s,l,s,g} (2)二维数组:int[,] arr=new int[2,2]{{1,2},{3,4}} 类型[,] 数组名=new 类型[行数(元素数),列数(元素的子元素数]{{元素1,元素2},{元素…},…,} l  动态数组:类型[,] 数组名=new 类型[M,N],int M=””;int N=””; l  查看内部元素:foreach(int n in arr

KnockoutJS学习笔记10:KonckoutJS foreach绑定

KnockoutJS foreach绑定用来处理数组,通常用来将一个数组绑定到一个列表或者table中.在foreach绑定中,我们可以使用if.with等嵌套绑定. 示例代码: <table> <thead> <tr><th>First name</th><th>Last name</th></tr> </thead> <tbody data-bind="foreach: peop

VBA学习笔记之随机数&amp;数组redim

发现更简单的: a=Application.RandBetween(-10, 10) 直接生成-10到10之间的随机整数 关于二维数组Redim Preserve: 如果使用了 Preserve 关键字,就只能重定义数组最末维的大小,且根本不能改变维数的数目. 具体参考 1 如果使用了 Preserve 关键字,就只能重定义数组最末维的大小,且根本不能改变维数的数目.例如,如果数组就是一维的,则可以重定义该维的大小,因为它是最末维,也是仅有的一维.不过,如果数组是二维或更多维时,则只有改变其最末