knockoutjs如何动态加载外部的file做为component中的template数据源

  玩过knockoutjs的都知道,有一个强大的功能叫作component,而这个component有个牛逼的地方就是拥有本身的viewmodel和template,javascript

好比下面这样:html

 ko.components.register('message-editor', {
            viewModel: function(){},
            template:""
        });

 

很显然,viewmodel就是function函数区,而template就是模板区,而后经过register函数将component注册到knockout中,下面咱们演示一个简单java

的功能,就是动态的显示当前“input”内容的length长度。jquery

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <meta charset="utf-8" />
    <script src="jquery-1.8.2.js"></script>
    <script src="knockoutjs.js"></script>
</head>
<body>
    <div data-bind='component: "message-editor"'></div>

    <script type="text/javascript">

        ko.components.register('message-editor', {
            viewModel: function (params) {
                this.text = ko.observable(params && params.initialText || '');
            },
            template: 'Message: <input data-bind="value: text" /> '
                    + '(length: <span data-bind="text: text().length"></span>)'
        });

        ko.applyBindings();
    </script>

</body>
</html>

 

      请仔细看一下这段代码,当前的component会将template模板inject到html的div的标签中,并且这个template标记中还有一个text元素的绑定,ajax

而这个(text().length)的数据源恰好就是viewModel中的this.text..对吧。。。有了这两个的合一,咱们最后的html展现以下:app

 

接下来咱们随便输入一些数字,移开鼠标,这个时候会触发input的change事件,好比下面这样。ide

是否是好吊??? 固然有些人可能要问,若是在input呈现的时候赋予一点默认值呢???可不能够呢?固然也是能够的,这个时候咱们能够在模块化

data-bind中默认赋予值就ok啦。。。好比下面这样:函数

 1 <body>
 2     <h4>Second instance, passing parameters</h4>
 3     <div data-bind='component: { name: "message-editor", params: { initialText: "Hello, world!" }}'></div>
 4 
 5     <script type="text/javascript">
 6 
 7         ko.components.register('message-editor', {
 8             viewModel: function (params) {
 9                 this.text = ko.observable(params && params.initialText || '');
10             },
11             template: 'Message: <input data-bind="value: text" /> '
12                     + '(length: <span data-bind="text: text().length"></span>)'
13         });
14 
15         ko.applyBindings();
16     </script>
17 </body>

 

      能够看到,上面的代码中我经过在component中的params对象中加入一个initialText属性,这个时候就能够将这个initialText动态的注入到ui

咱们的viewModel中,而后咱们的input和span元素经过data-bind 订阅了这个viewModel中的this.text监控属性,这个时候就出现了实时更新操

做了,火烧眉毛的看一下吧~

 

一:问题分析

    好了,经过上面的演示,你或许发现到了以下两个问题,第一个问题就是好强大,只要你register就能够了,根本不须要经过applyBindings来

施加一个viewmodel,这样就实现了页面的模块化,真的好便捷~ 因此这个问题是一个好事情, 第二个问题就是咱们的template模板中的内容是

经过“硬编码“的形式,也就是若是这个内容有不少,好比有100行,200行,那咱们是否是疯了??? 就是你能耐再大也无法一一拼接起来,就算

拼起来,维护成本也太大了,因此问题来了,如何将template的content动态化??? 好比现实中咱们看到的 百度文库 的页面。。。以下图:

 

这个页面中,有不少的模块,好比我圈出来的上面3个,这三个模块中的html确定仍是不少的吧~~~

 

二:template动态获取

  html内容的动态获取,一般有两种方式,第一种就是RequireJs,固然你须要引用这么一个js,第二种就是咱们重写他们的模板,固然这篇我

们讲解后面的这种方式,咱们要作的就是重写component中的loadTemplate函数,而后替换默认的defaultLoader加载器,是否是很简单呢???

 

1. 重写loadtemplate方法

//第一步:重写loadTemplate方法
var templateFromUrlLoader = {
    loadTemplate: function(name, templateConfig, callback) {
        if (templateConfig.fromUrl) {
            var fullUrl = '/' + templateConfig.fromUrl
            
            //ajax动态获取外部的file内容
            $.get(fullUrl, function(markupString) {
                ko.components.defaultLoader.loadTemplate(name, markupString, callback);
            });
        } else {
            callback(null);
        }
    }
};

//替换原来的defaultLoader,实现新的templateFromUrlLoader
ko.components.loaders.unshift(templateFromUrlLoader);

 

2. 将hard codeing 放入到外部的file,好比我新建了一个file.html文件。

 

3. 再register组件,而后在template标记上引用外面文件路径,好比下面的{ fromUrl: 'file.html' }

        ko.components.register('message-editor', {
            viewModel: function (params) {
                this.text = ko.observable(params && params.initialText || '');
            },
            template: { fromUrl: 'file.html' },
        });

 

好了,全部功能都准备完毕了,咱们浏览一下页面,看看是啥样的???

终于大功搞成了,对不对撒~~~而后是否是就能够延伸到上面介绍的“百度文库”的例子,咱们能够把各个模块的html放到一个单独的文件中,

对吧,好了,本篇就说到这里,但愿对你有帮助~~~

 

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <meta charset="utf-8" />
    <script src="jquery-1.8.2.js"></script>
    <script src="knockoutjs.js"></script>
</head>
<body>
    <div data-bind='component: { name: "message-editor", params: { initialText: "你好撒!!!" }}'></div>

    <script type="text/javascript">

        //第一步:重写loadTemplate方法
        var templateFromUrlLoader = {
            loadTemplate: function (name, templateConfig, callback) {
                if (templateConfig.fromUrl) {
                    var fullUrl = '/' + templateConfig.fromUrl

                    //ajax动态获取外部的file内容
                    $.get(fullUrl, function (markupString) {
                        ko.components.defaultLoader.loadTemplate(name, markupString, callback);
                    });
                } else {
                    callback(null);
                }
            }
        };

        //替换原来的defaultLoader,实现新的templateFromUrlLoader
        ko.components.loaders.unshift(templateFromUrlLoader);

        ko.components.register('message-editor', {
            viewModel: function (params) {
                this.text = ko.observable(params && params.initialText || '');
            },
            template: { fromUrl: 'file.html' },
        });

        ko.applyBindings();
    </script>
</body>
</html>
View Code
相关文章
相关标签/搜索