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的模板绑定提供了很多的功能和支持,让我们对集合类型的处理更加方便,页面的结构更加清晰,脚本更加简洁。
knockoutJS学习笔记06:ko数组与模板绑定的更多相关文章
- knockoutJS学习笔记08:表单域绑定
前面的绑定都是用在基本标签上,这章主要讲表单域标签的绑定. 一.value 绑定 绑定标签:input text.textarea. <p>用户名:<input type=" ...
- RX学习笔记:JavaScript数组操作
RX学习笔记:JavaScript数组操作 2016-07-03 增删元素 unshift() 在数组开关添加元素 array.unshift("value"); array.un ...
- 机器学习实战(Machine Learning in Action)学习笔记————06.k-均值聚类算法(kMeans)学习笔记
机器学习实战(Machine Learning in Action)学习笔记————06.k-均值聚类算法(kMeans)学习笔记 关键字:k-均值.kMeans.聚类.非监督学习作者:米仓山下时间: ...
- iOS学习笔记06—Category和Extension
iOS学习笔记06—Category和Extension 一.概述 类别是一种为现有的类添加新方法的方式. 利用Objective-C的动态运行时分配机制,Category提供了一种比继承(inher ...
- Go语言学习笔记八: 数组
Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...
- jQuery学习笔记之DOM操作、事件绑定(2)
jQuery学习笔记之DOM操作.事件绑定(2) --------------------学习目录------------------------ 4.DOM操作 5.事件绑定 源码地址: https ...
- C语言学习笔记之成员数组和指针
成员数组和指针是我们c语言中一个非常重要的知识点,记得以前在大学时老师一直要我们做这类的练习了,但是最的还是忘记了,今天来恶补一下. 单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个 ...
- KnockoutJs学习笔记(五)
作为一名初学者来说,一篇篇的按顺序看官网上的文档的确是一件很痛苦的事情,毕竟它的排列也并非是由浅及深的排列,其中的顺序也颇耐人寻味,于是这篇文章我又跳过了Reference部分,进而进入到具体的bin ...
- Angular6 学习笔记——组件详解之模板语法
angular6.x系列的学习笔记记录,仍在不断完善中,学习地址: https://www.angular.cn/guide/template-syntax http://www.ngfans.net ...
随机推荐
- javascript创建对象的几种模式
在js中有几种模式可以创建对象,通过对象操作所包含的属性与方法. 一般来说,构造函数名称的第一个字母为大写字母,非构造函数名称的第一个字母为小写字母,当然,构造函数与一般函数唯一的区别只是调用的方式不 ...
- js 理解new的运行机制
先上段代码: function People(name) { this.name = name; } People.prototype.sayName = function () { console. ...
- 完美 全兼容 解决 文字两端对齐 justify 中文姓名对齐
text-align:justify; 所有浏览器都支持,text-justify之类的却只有IE支持,就不要考虑了. justify我的理解,使元素内部的子元素两端对齐,子元素当然只能是inline ...
- 深入了解 Authorize 和 AllowAnonymous
深入了解 Authorize 和 AllowAnonymous Chapter 0 - Intro 最近做的一个项目的时候,自定义授权 Attribute 来区分用户权限,我的项目不太大,权限控制也不 ...
- AngularJS中的指令全面解析(转载)
说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方.双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJ ...
- MyEclipse 2016 CI 1支持远程WebSphere连接器
MyEclipse 2016 CI 1有很多Web开发者会喜欢的新功能,包括Live Preview,带有Map支持和hot-swap功能的JavaScript调试.另外还新增支持远程WebSpher ...
- iOS 限制TextField输入长度(标准)
iOS 限制TextField输入长度(标准) 网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入 ...
- (三)Maven仓库介绍与本地仓库配置
1.Maven本地仓库/远程仓库的基本介绍 示意图: 本地仓库是指存在于我们本机的仓库,在我们加入依赖时候,首先会跑到我们的本地仓库去找,如果找不到则会跑到远程仓库中去找.对于依赖的包大家可以从这个地 ...
- 比Ansible更吊的自动化运维工具,自动化统一安装部署_自动化部署udeploy 1.0
新增功能: 2015-03-11 除pass(备份与更新)与start(启动服务)外,实现一切自动化. 注:pass与start设为业务类,由于各类业务不同,所以无法实现自动化.同类业务除外,如更新的 ...
- Gui系统之View体系(2)---View的setContent
1.从SetContentView讲起 1.1Activty的setContentView里面的内容 public void setContentView(@LayoutRes int layoutR ...