zoukankan      html  css  js  c++  java
  • KnockoutJS-模板绑定

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

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

    一、模板绑定目的

      在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://gitee.com/530521314/Partner.TreasureChest.git

    2018-10-13,望技术有成后能回来看见自己的脚步
  • 相关阅读:
    windows&nbsp;下搭建apache&nbsp;php&nbsp;mysql&nbsp;p…
    PHP&nbsp;VC9和VC6以及Thread&nbsp;Safe和Non…
    mysql数据库插入中文时出现ERROR&nbsp;1…
    phpmyadmin&nbsp;配置
    Linux系统安装时分区的选择【转】
    汉字 Unicode 编码范围
    Linux 程序后台运行
    添加用户username到sudo组
    nautilus
    记录一下自己的.tmux.conf,.vimrc
  • 原文地址:https://www.cnblogs.com/CKExp/p/9296345.html
Copyright © 2011-2022 走看看