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
相關文章
相關標籤/搜索