Knockout应用开发指南 第四章:模板绑定

模板绑定The template binding

目的

template绑定通过模板将数据render到页面。模板绑定对于构建嵌套结构的页面非常方便。默认情况, Knockout用的是流行的jquery.tmpl模板引擎。使用它的话,需要在安装页面下载和引用jquery.tmpl和jQuery框架。或者你也可以集成其它的模板引擎(虽然需要了解Knockout 内部知识才行)。

例子

<div data-bind=‘template: "personTemplate"‘> </div>
<script id=‘personTemplate‘ type=‘text/html‘>
    ${ name } is ${ age } years old
    <button data-bind=‘click: makeOlder‘>Make older</button>
</script> 

<script type=‘text/javascript‘>
    var viewModel = {
        name: ko.observable(‘Bert‘),
        age: ko.observable(78),
        makeOlder: function () {
            this.age(this.age() +1);
        }
    };
    ko.applyBindings(viewModel);
</script>

当引用的observable(dependent observable)数据改变的时候,Knockout会自动重新render模板。在这个例子里,每次点击button的时候都会重新render模板。

语法

你可以使用任何你模板引擎支持的语法。jquery.tmpl执行如下语法:

和observable数组一起使用{{each}}

当然使用{{each someArray}}的时候,如果你的值是observableArray,你必须使用JavaScript类型的基础数组类型{{each myObservableArray()}},而不是{{each myObservableArray}}。

参数

主参数

语法快速记忆:如果你声明的仅仅是字符串(上个例子),KO会使用模板的ID来render。应用在模板上的数据是你的整个view model对象(例如ko.applyBindings 绑定的对象)。

更多控件,你可以传带有如下属性的JavaScript对象:

name(必选项) — 需要render的模板ID – 参考 注5 如何使用function函数声明ID。

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

foreach(可选项) — 指定KO按照“foreach”模式render模板 – 参考 注3。

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

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

传递多个参数的例子:

<div data-bind=‘template: { name: "personTemplate", data: someObject }‘> </div>

注1:Render嵌套模板

因为在模板里使用的是data-bind属性来声明的,所以嵌套模板你可以再次使用data-bind=‘template: ...‘,在上层模板的元素里。

这比模板引起的原生语法好用多了(例如jquery.tmpl里的{{tmpl}})。Knockout语法的好处在于可以在每层模板的跟着相关的依赖值,所以如果依赖改变了,KO将只会重新render依赖所在的那个模板。这将很大地改善了性能。

注2:${ val }和<span data-bind=‘text: val‘></span>有何不同?

当你在模板内部使用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 }语法比较简洁,如果你的模板比较小的话,还是更合适的,不会带来大的性能问题。

注3:使用foreach

如果需要为集合里的每一个item render一次模板,有2种方式:

你可以使用模板引擎里的原生“each”语法,对jquery.tmpl来说就是用{{each}}语法迭代数组。

另外一种方式就是用Knockout的foreach模式来render。

例子:

<div data-bind=‘template: { name: "personTemplate",
                            foreach: someObservableArrayOfPeople }‘> </div>

foreach模板模式的好处是:

  • 当往你的collection集合里添加新item项的时候,KO只会对这个新item进行render模板,并且将结果附加到现有的DOM上。
  • 当从collection集合里删除item的时候,KO将不会重新render任何模板,而只是简单地删除相关的元素。
  • KO允许通过自定义的方式声明afterAdd和beforeRemove的callback函数添加/删除DOM元素。然后这个callback会在删除元素的时候进行一些动画或者其它操作。

与原生的each不同之处是:在改变之后,模板引擎强制重新render模板里所有的内容,因为它根本就不关注KO里所谓的依赖跟踪内容。

关于使用foreach模式的例子,参考grid editor和animated transitions。

注4:使用afterRender选项

有时候,你需要在模板生成的DOM元素上深度定义逻辑。例如,你可能想再模板输出的时候进行截获,然后在render的元素上允许jQuery UI命令(比如date picker,slider,或其它)。

你可以使用afterRender选项,简单声明一个function函数(匿名函数或者view model里的函数),在render或者重新render模板之后Knockout会重新调用它。如果你使用的是foreach,那在每个item添加到observable数组之后, Knockout会立即调用afterRender的callback函数。例如,

<div data-bind=‘template: { name: "personTemplate",
                            data: myData,
                            afterRender: myPostProcessingLogic }‘> </div>

… 在view model里声明一个类似的函数(例如,对象包含myData):

viewModel.myPostProcessingLogic = function (elements) {
    // "elements" is an array of DOM nodes just rendered by the template
    // You can add custom post-processing logic here
}

注5:动态决定使用哪个模板

有时候,你可能需要根据数据的状态来决定使用哪个模板的ID。可以通过function的返回ID应用到name选择上。如果你用的是foreach模板模式, Knockout会对每个item执行function(将item作为参数)从而将返回值作为ID,否则,该function接受的参数是整个 data option或者是整个view model。

例子:

<ul data-bind=‘template: { name: displayMode,
                           foreach: employees }‘> </ul>
<script type=‘text/javascript‘>
var viewModel = {
    employees: ko.observableArray([
        { name: "Kari", active: ko.observable(true) },
        { name: "Brynn", active: ko.observable(false) },
        { name: "Nora", active: ko.observable(false) }
    ]),
    displayMode: function (employee) {
        return employee.active() ?"active" : "inactive";
        // Initially "Kari" uses the "active" template, while the others use "inactive"
    }
};

// ... then later ...
viewModel.employees()[1].active(true);
// Now "Brynn" is also rendered using the "active" template.
</script>

如果你的function引用的是observable值,那当这些值改变的时候,绑定的值会随着改变的。这将导致相应的模板重新render。

注6:使用templateOptions传递额外的参数

如果你在绑定模板的时候需要传入额外的数据的话,你可以使用templateOptions对象来传递这些值。这可以帮助你通过一些 不属于view model过滤条件或者字符来重用模板。另外一个好处是用在范围控制,你可以引用通过你的模板访问怒道的数据。

例子,

<ul data-bind=‘template: { name: "personTemplate",
                           foreach: employees,
                           templateOptions: { label: "Employee:",
                                              selectedPerson: selectedEmployee } }‘> </ul>

<script id=‘personTemplate‘ type=‘text/html‘>
    <div data-bind="css: { selected: $data === $item.selectedPerson()" }">
        ${ $item.label } <input data-bind="value: name" />
    </div>
</script>

在整个例子里,personTemplate有可能都使用employee和自定义对象。通过templateOptions我们可以传递一个字符label和当前已选择项作为selectedPerson来控制style。在jquery.tmpl模板里,这些值可以通过访问$item对象的属性得到。

注7:模板是被预编译和缓存的

为了最大性能,Knockout内嵌模板引擎jquery.tmpl会利用自身的功能对你的模板进行预编译成可执行的JavaScript代码,然后从编译流程里缓存输出。这将使模板更快更加具有可执行性,尤其是是使用foreach循环来render相同模板的时候。

一般情况你不会注意到这个,所以经常会忘记。不过,当你在某种原因下通过编程重写模板<script>元素的时候并且该模板之前已经用过一次的话,你的改变不会带来任何render的变化,因为在第一次使用的时候已经预编译了并且缓存起来了。(如果这些会带来问题,我们将考虑在KO新版本里提供一个禁用或重设模板缓存的功能,不过好像没有好的原因去动态改变模板<script>元素的内容)。

注8:使用不同的模板引擎

如果你想使用不同的JavaScript模板引擎(或者是因为某些原因你不想在jQuery上使用依赖)。我们可以去为KO来写一个不同的模板引擎,例如,在KO源代码里的jqueryTmplTemplateEngine.js,尽管他是为了支持多个版本的jquery.tmpl而编译。支持一个单独的模板引擎版本相对简单多了。

依赖性

template绑定只能在引用合适的模板引擎情况下才能工作。例如提到的jquery.tmpl引擎。

版权声明:本文为博主http://www.zuiniusn.com原创文章,未经博主允许不得转载。

时间: 2024-10-12 21:23:00

Knockout应用开发指南 第四章:模板绑定的相关文章

Knockout应用开发指南 第三章:绑定语法

12   value 绑定 目的 value绑定是关联DOM元素的值到view model的属性上.主要是用在表单控件<input>,<select>和<textarea>上. 当用户编辑表单控件的时候, view model对应的属性值会自动更新.同样,当你更新view model属性的时候,相对应的元素值在页面上也会自动更新. 注:如果你在checkbox或者radio button上使用checked绑定来读取或者写入元素的 checked状态,而不是value

Knockout应用开发指南 第五章:创建自定义绑定

创建自定义绑定 你可以创建自己的自定义绑定 – 没有必要非要使用内嵌的绑定(像click,value等).你可以你封装复杂的逻辑或行为,自定义很容易使用和重用的绑定.例如,你可以在form表单里自定义像grid,tabset等这样的绑定. 重要:以下文档只应用在Knockout 1.1.1和更高版本,Knockout 1.1.0和以前的版本在注册API上是不同的. 注册你的绑定 添加子属性到ko.bindingHandlers来注册你的绑定: ko.bindingHandlers.yourBin

IOS开发指南第四章 IOS8多分辨率屏幕适配 学习

1 获取IOS设备屏幕信息 CGSize iOSDeviceScreenSize = [UIScreen mainScreen].bounds.size; NSString *s = [NSString stringWithFormat:@"%.0f x %.0f", iOSDeviceScreenSize.width, iOSDeviceScreenSize.height]; 获取设备信息判断是否是ipone-判断横屏还是竖屏-判断设备型号 属性userInterfaceIdiom是

Knockout应用开发指南 第七章:Mapping插件

Mapping插件 Knockout设计成允许你使用任何JavaScript对象作为view model.必须view model的一些属性是observable的,你可以使用KO绑定他们到你的UI元素上,当这些observable值改变的时候,这些UI元素就会自动更新. 绝大多数程序都需要从服务器端获取数据,但是由于服务器不知道observable的概念是什么,它只支持简单的JavaScript对象(通常是序列化以后的JSON),mapping插件可以让你很方便地将简单JavaScript对象

Knockout应用开发指南

第一章:入门 1.Knockout简介 (Introduction) Knockout是一个轻量级的UI类库,通过应用MVVM模式使JavaScript前端UI简单化. Knockout有如下4大重要概念: 声明式绑定 (Declarative Bindings):使用简明易读的语法很容易地将模型(model)数据关联到DOM元素上. UI界面自动刷新 (Automatic UI Refresh):当您的模型状态(model state)改变时,您的UI界面将自动更新. 依赖跟踪 (Depend

Knockout应用开发指南 第九章:高级应用举例

原文:Knockout应用开发指南 第九章:高级应用举例 1   Contacts editor 这个例子和微软为演示jQuery Data Linking Proposal例子提供的例子一样的提供的,我们可以看看Knockout实现是难了还是容易了. 代码量的多少不重要(尽快Knockout 的实现很简洁),重要的看起来是否容易理解且可读.查看HTML源代码,看看如何实现的view model以及绑定的. 代码: View <h2>Contacts</h2><div id=

MiS603开发板 第四章 流水灯实验

作者:MiS603开发团队 日期:20150911 公司:南京米联电子科技有限公司 论坛:www.osrc.cn 网址:www.milinker.com 网店:http://osrc.taobao.com EAT博客:http://blog.chinaaet.com/whilebreak 博客园:http://www.cnblogs.com/milinker/ MiS603开发板 第四章 流水灯实验 关于流水灯,网上有太多的例子了.其实只要掌握上面分频计数的技巧,设计流水灯是件极其简单的事情.从

Android艺术开发探索第四章——View的工作原理(下)

Android艺术开发探索第四章--View的工作原理(下) 我们上篇BB了这么多,这篇就多多少少要来点实战了,上篇主席叫我多点自己的理解,那我就多点真诚,少点套路了,老司机,开车吧! 我们这一篇就扯一个内容,那就是自定义View 自定义View 自定义View的分类 自定义View的须知 自定义View的实例 自定义View的思想 一.自定义View的分类 自定义View百花齐放,没有什么具体的分类,不过可以从特性大致的分为4类,其实在我看来,就三类,继承原生View,继承View和继承Vie

Knockout应用开发指南 第十章:更多信息(完结篇)

原文:Knockout应用开发指南 第十章:更多信息(完结篇) 1   浏览器支持 Knockout在如下浏览器通过测试: Mozilla Firefox 2.0+(最新测试版本:3.6.8) Google Chrome(通过Windows and Mac 下的version 5测试:其它低版本也该可以工作) Microsoft Internet Explorer 6, 7, 8 Apple Safari(Windows下的Safari 5测试,Mac OS X下的 Safari 3.1.2测试