KnockoutJS基础知识(三)

  对于knockoutJS来讲,模板绑定和Mapping插件绑定是十分重要的功能,虽然模板绑定在我工作中用的及其少,但模板绑定的重要性不可忽视,在其他前端框架中,如Angular、Vue等等,模板存在的意义十分重要,Mapping插件使得我们能够脱离手工绑定,及其方便我们快速绑定达到预期效果。

  KnockoutJS模型绑定更多用法:https://knockoutjs.com/documentation/template-binding.html

  本文地址:https://www.cnblogs.com/CKExp/p/9296345.html

  本文demo地址:https://gitee.com/530521314/koInstance.git

一、模板绑定目的

  在mvc的开发中,对于常用的一些独立的Html,习惯将它变成分布视图或是视图组件,以此来方便调用以及重用,同时也达到解耦效果,同样在前端开发中,对于部分重用度很高、复杂度高的UI、嵌套UI等这些部分,我们也可以设计成模板。

  

  在knockoutJS中通过template绑定将模板绑定到预期DOM元素中,将模板所依赖的数据呈现。模板绑定对于构建嵌套结构的页面十分方便,默认情况, Knockout使用jquery.tmpl模板引擎,使用模板绑定时,需引用jquery.tmpl和jQuery框架,或者你也可以集成其它的模板引擎(需要了解Knockout 内部知识)。

  模板语法:

  • ${ someValue }
  • {{html someValue}}
  • {{if someCondition}}
  • {{else someCondition}}
  • {{each someArray}}

  具体了解模板语法可以查看:http://www.php.cn/js-tutorial-383558.html

二、模板绑定应用

  如果你仅仅是声明的字符串,KO将会使用它作为模板的ID去渲染。应用在模板上的数据是你当前的viewModel对象。

  1、构建一个简单模板

<hr />
<label>标准模板</label>
<div data-bind="template: ‘personTemplate‘"></div>
<script id=‘personTemplate‘ type=‘text/html‘>
    ${ name } 是 ${ age } 岁
    <button class="btn btn-primary" data-bind=‘click: makeOlder‘>增长一岁</button>
</script>

@section Scripts{
    <script type=‘text/javascript‘>
        var viewModel = {
            name: ko.observable(‘刺客‘),
            age: ko.observable(20),
            makeOlder: function () {
                viewModel.age(viewModel.age() + 1);
            }
        };

        $(function () {
            ko.applyBindings(viewModel);
        })
    </script>
}

  通过设计一个简单的模板,在viewModel中的name或age发生改变后,Knockout将自动重新render模板。在该例子里,每次点击按钮都会重新渲染该模板。

  2、构建一个性能更好点的简单模板

<br /><hr />
<label>增强版</label>
<div data-bind="template: ‘personAdvancedTemplate‘"></div>
<script id=‘personAdvancedTemplate‘ type=‘text/html‘>
    <label data-bind="text:name()+‘是‘+age()+‘岁‘"></label>
    <button class="btn btn-primary" data-bind=‘click: makeOlder‘>增长一岁</button>
</script>

@section Scripts{
    <script type=‘text/javascript‘>
        var viewModel = {
            name: ko.observable(‘刺客‘),
            age: ko.observable(20),
            makeOlder: function () {
                viewModel.age(viewModel.age() + 1);
            }
        };

        $(function () {
            ko.applyBindings(viewModel);
        })
    </script>
}

  通过data-bind的形式将属性绑定时,如果属性改变了,将直接改变值,而无需重新渲染模板,这比通过${property}方式更加高效点,但是如果说模板内容较小较简单,直接使用${property}这种方式也是可行的,浪费点性能,写起来快捷方便。

  3、嵌套模板

<br /><hr />
<label>嵌套模版</label>
<div data-bind="template: ‘firstPersonAdvancedTemplate‘"></div>
<script id=‘firstPersonAdvancedTemplate‘ type=‘text/html‘>
    <label data-bind="text:name()+‘是‘+age()+‘岁‘"></label>
    <button class="btn btn-primary" data-bind=‘click: makeOlder‘>增长一岁</button>
    <div style="border:1px dotted red;" data-bind="template: ‘secondPersonAdvancedTemplate‘"></div>
</script>
<script id=‘secondPersonAdvancedTemplate‘ type=‘text/html‘>
    <label data-bind="text:name()+‘是‘+age()+‘岁‘"></label>
    <button class="btn btn-primary" data-bind=‘click: makeOlder‘>增长一岁</button>
</script>
@section Scripts{
    <script type=‘text/javascript‘>
        var viewModel = {
            name: ko.observable(‘刺客‘),
            age: ko.observable(20),
            makeOlder: function () {
                viewModel.age(viewModel.age() + 1);
            }
        };

        $(function () {
            ko.applyBindings(viewModel);
        })
    </script>
}

  效果:

  

  嵌套模板是在一个模板的基础上,在模板中继续使用data-bind的形式利用template嵌套其他模板,模板的重新渲染以就近原则为主,最近的模板数据改变,只渲染最近的模板,对于所有的模板不进行重新渲染。

  4、foreach模板

  在模板中使用foreach完成相应的循环显示时,有两种方式,一种使用模板语法{{each personArray}}这种形式 ,但是这种在性能上不如直接使用data-bind的方式,因此我将直接使用data-bind完成foreach模板绑定,

<br /><hr />
<label>foreach模板</label>
<ul data-bind="template: { name: ‘dynastyForeachTemplate‘,foreach: dynastys,afterAdd:afterAddFunc,beforeRemove:beforeRemoveFunc }"></ul>
<script id=‘dynastyForeachTemplate‘ type=‘text/html‘>
    <li><label data-bind="text:dynastyName()+‘是‘+dynastyAge()+‘年‘"></label></li>
</script>
@section Scripts{
    <script type=‘text/javascript‘>
        function dynastyViewModel(name, age) {
            dynastyName = ko.observable(name);
            dynastyAge = ko.observable(age);
        }

        var viewModel = {
            dynastys: ko.observableArray([new dynastyViewModel("秦朝", 30)]),
            afterAddFunc: function () {
                console.log("afterAddFunc");
            },
            beforeRemoveFunc: function () {
                console.log("beforeRemoveFunc");
            },
            addDynasty: function () {
                console.log("addDynasty");
                viewModel.dynastys.push(new dynastyViewModel("", 0));
            },
            deleteDynasty: function (dynasty) {
                console.log("deleteDynasty");
                viewModel.dynastys.remove(dynasty);
            }
        };

        $(function () {
            ko.applyBindings(viewModel);
            viewModel.dynastys.push(new dynastyViewModel("唐朝", 300));
            viewModel.dynastys.push(new dynastyViewModel("宋朝", 300));
            viewModel.dynastys.push(new dynastyViewModel("元代", 300));
        })
    </script>
}

  

  对于复杂的模板来讲,需要循环使用如跟帖回帖操作,只有内容不同、时间不同等等,其他html元素是一样的,则使用这种方式能大幅提高开发效率。当增加一个Item到fo‘reach关联的数组集合中时,只会将Item部分进行模板的重新渲染,其余已有的部分不影响,

当删除Item项时,模板不执行渲染,只是将Item从集合中移除。

  5、table模板

<br /><hr />
<label>table模板</label>
<table class="table table-bordered">
    <thead>
        <tr>
            <th>朝代</th>
            <th>存活时间</th>
            <th></th>
        </tr>
    </thead>
    <tbody data-bind="template:  { name: ‘dynastyTableTemplate‘, foreach: dynastys,afterAdd:afterAddFunc,beforeRemove:beforeRemoveFunc }"></tbody>
    <tfoot>
        <tr>
            <td colspan="3" class="text-center"><button class="btn btn-primary" data-bind="click:addDynasty">增加朝代</button></td>
        </tr>
    </tfoot>
</table>
<script id=‘dynastyTableTemplate‘ type=‘text/html‘>
    <tr>
        <td><input data-bind="value:dynastyName" /></td>
        <td><input data-bind="value:dynastyAge" /></td>
        <td><button class="btn btn-danger" data-bind="click:$root.deleteDynasty">删除</button></td>
    </tr>
</script>

@section Scripts{
    <script type=‘text/javascript‘>
        function dynastyViewModel(name, age) {
            dynastyName = ko.observable(name);
            dynastyAge = ko.observable(age);
        }

        var viewModel = {
            dynastys: ko.observableArray([new dynastyViewModel("秦朝", 30)]),
            afterAddFunc: function () {
                console.log("afterAddFunc");
            },
            beforeRemoveFunc: function () {
                console.log("beforeRemoveFunc");
            },
            addDynasty: function () {
                console.log("addDynasty");
                viewModel.dynastys.push(new dynastyViewModel("", 0));
            },
            deleteDynasty: function (dynasty) {
                console.log("deleteDynasty");
                viewModel.dynastys.remove(dynasty);
            }
        };

        $(function () {
            ko.applyBindings(viewModel);
            viewModel.dynastys.push(new dynastyViewModel("唐朝", 300));
            viewModel.dynastys.push(new dynastyViewModel("宋朝", 300));
            viewModel.dynastys.push(new dynastyViewModel("元代", 300));
        })
    </script>
}

  对于table模板的实际用法与foreach模板是一样的,在foreach模板中也同样可以看见table模板的效果展示。

  data-bind下template的绑定参数有

name(必选项) — 需要render的模板ID,可以通过对绑定属性中值的动态变换,切换不同的模板使用。

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

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

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

templateOptions(可选项) — 在渲染模板时可传递额外数据以便使用,可帮助你使用一些不属于viewModel过滤条件或者字符来重用模板。

  当然还有其他模板引擎可以使用,但是就目前来讲,个人感觉jquery.tmpl引擎已经满足我的需求了。

  本文地址:https://www.cnblogs.com/CKExp/p/9296345.html

  本文demo地址:https://gitee.com/530521314/koInstance.git

2018-10-13,望技术有成后能回来看见自己的脚步

原文地址:https://www.cnblogs.com/CKExp/p/9296345.html

时间: 2024-10-21 09:54:24

KnockoutJS基础知识(三)的相关文章

20_Shell语言———VIM编辑器基础知识三之窗口属性定制、配置文件及查找替换功能

Vim编辑器可以让用户按照需求来定制一些使用属性. 一.窗口属性定义 1)显示行号 行号不是内容,只是用来帮助用户确认文本所在的行.在vim编辑器中,如果要显示行号,可以在末行模式下输入: set number 如果想关闭,则可以在功能名称前面加上no,即: set nonumber 命令可以被简写,如set number 可以简写为 set nu:set nonumber 可以简写为 set nonu. 注意,上述设定仅对当前vim的进程有效,一旦当前进程关闭,这些设定就会失效,如果要使设定永

计算机科学基础知识(三)静态库和静态链接

三.将relocatable object file静态链接成可执行文件 将relocatable object file链接成可执行文件分成两步,第一步是符号分析(symbol resolution),第二步是符号重新定位(Relocation).本章主要描述这两个过程,为了完整性,静态库的概念也会在本章提及. 1.为什么会提出静态库的概念? 程序逻辑有共同的需求,例如数学库.字符串库等,如果每个程序员在撰写这些代码逻辑的时候都需要自己重新写那么该是多么麻烦的事情,而且容易出错,如果有现成的,

Dapper基础知识三

在下刚毕业工作,之前实习有用到Dapper?这几天新项目想用上Dapper,在下比较菜鸟,这块只是个人对Dapper的一种总结. Dapper,当项目在开发的时候,在没有必要使用依赖注入的时候,如何做到对项目的快速开发这里对Dapper做一个小的进阶. 结合上一篇的博客,就可以使用了. public class Demo { public string name { get; set; } public string DapperTest { get; set; } } public class

KnockoutJS基础知识(四)

几乎所有Web应用程序都要和服务器端交换数据,交换数据时最方便的就是使用JSON格式.Knockout可以实现很复杂的客户端交互,对于前后端交互使用的技术最为基本且常用的是Ajax,本次利用Ajax和ko的双向绑定完成一些简单的功能,可以快速展示出ko的方便之处. Demo地址: https://gitee.com/530521314/koInstance.git 一.服务端返回数据绑定到客户端 1.准备好一些初始数据,直接通过View方法将视图实体返回到视图文件中. 2.前端设置为强类型,初始

【基础知识三】线性模型

一.基本形式 通过属性的线性组合来进行预测, 许多非线性模型可以在线性模型的基础上,引入层级结构或高维映射而得. 二.线性回归 最小二乘法:求解ω和b: 多元线性回归:样本由多个属性描述,即x为多维向量: 若矩阵不满秩产生多个解,解决方法:引入正则化项: 三.对数/逻辑线性回归 广义线性模型: g(.)条件:连续且充分光滑(单调可微) 为了预测值连续,引入Sigmoid函数 得到, 极大似然估计:求解ω和b 四.线性判别分析LDA 也叫"Fisher判别" 将样例投影到一条直线上,使同

3. K线基础知识三

1. 阴线 证券市场上指开盘价高于收盘价的K线,K线图上一般用淡蓝色标注,表示股价下跌,当收盘价低于开盘价,也就是股价走势呈下降趋势时,我们称这种形态的K线为阴线. 中间部分实体为蓝色,此时,上影线的长度表示最高价和开盘价之间的价差.实体的长短代表开盘价比收盘价高出的幅度.下影线的长度则有收盘价和最高价之间的价差大小所决定. 2. 小阴星 小阴星的分时走势图与小阳星相似,只是收盘价格略低于开盘价格.表明行情疲软,发展方向不明. 3. 小阴线 表示空方呈打压态势,但力度不大. 4. 光脚阴线 光脚

Linux基础知识三

1.列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可. 查看系统用户的命令为: (1)getent passwd 查看系统上的所有用户信息 (2)w 查看登录用户正在使用的进程信息,该命令所使用的信息来源于/var/run/utmp文件 w命令输出的信息包括: -用户名称 -用户的机器名称或tty号 -远程主机地址 -用户登录系统的时间 -空闲时间(作用不大) -附加到tty(终端)的进程所用的时间(JCPU时间) -当前进程所用时间(PCPU时间) -用户当

cocos2d0基础知识三个音符

1.触摸屏事件: bool HelloWorld::init() { //省略的代码的最后位 this->schedule(schedule_selector(HelloWorld::usecreatesprite),2);//定时器 this->setTouchEnabled(true);/CCLayer是能够对应点击对象的,默认情况是没开启的,我们通过this->setTouchEnabled(true)来设置是否接受触摸事件. return true; } void HelloWo

SQL Server基础知识三十三问 (15-21)

15. 存储过程可以调用自己么, 或者说可能有递归的存储过程么? SP nesting最多可以到多少层? 答: 可以的. 因为Transact-SQL 支持递归, 你可以编写可以调用自己的存储过程. 敌对可以被定义为一种解决问题的方法, 其中问题的解决是通过不断的对问题的子集调用自己而达成的. 当一个存储过程调用另一个存储过程或执行CLR的routine, type, 或aggregate时, 就会形成嵌套(nest). 你最多可以嵌套存储过程或托管代码的层级为32层.   16. 什么是log