knockoutjs动态加载外部的file作为component中的template数据源的实现方法

玩过knockoutjs的都知道,有一个强大的功能叫做component,而这个component有个牛逼的地方就是拥有自己的viewmodel和template,比如下面这样:

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

很显然,viewmodel就是function函数区,而template就是模板区,然后通过register函数将component注册到knockout中,下面我们演示一个简单的功能,就是动态的显示当前“input”内容的length长度。

<!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元素的绑定,而这个(text().length)的数据源刚好就是viewModel中的this.text..对吧。。。有了这两个的合一,我们最后的html展示如下:

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

是不是好吊??? 当然有些人可能要问,如果在input呈现的时候赋予一点默认值呢???可不可以呢?当然也是可以的,这个时候我们可以在data-bind中默认赋予值就ok啦。。。比如下面这样:

<body>
<h4>Second instance, passing parameters</h4>
<div data-bind='component: { name: "message-editor", params: { initialText: "Hello, world!" }}'></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>

可以看到,上面的代码中我通过在component中的params对象中加入一个initialText属性,这个时候就可以将这个initialText动态的注入到我们的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>

以上所述是小编给大家介绍的knockoutjs动态加载外部的file作为component中的template数据源的实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • KnockoutJS 3.X API 第四章之click绑定

    目的 click绑定主要作用是用于DOM元素被点击时调用相关JS函数.最常见用于button.input.a元素. 例如: You've clicked 0timesClick me 源码: <div> You've clicked <span data-bind="text: numberOfClicks"></span> times <button data-bind="click: incrementClickCounter&q

  • BootstrapTable与KnockoutJS相结合实现增删改查功能【一】

    Bootstrap是一个前端框架,解放Web开发者的好东东,展现出的UI非常高端大气上档次,理论上可以不用写一行css.只要在标签中加上合适的属性即可. KnockoutJS是一个JavaScript实现的MVVM框架.非常棒.比如列表数据项增减后,不需要重新刷新整个控件片段或自己写JS增删节点,只要预先定义模板和符合其语法定义的属性即可.简单的说,我们只需要关注数据的存取. 一.Knockout.js简介 1.Knockout.js和MVVM 如今,各种前端框架应接不暇,令人眼花缭乱,有时不得

  • Bootstrap与KnockoutJs相结合实现分页效果实例详解

    KnockoutJS是一个JavaScript实现的MVVM框架.非常棒.比如列表数据项增减后,不需要重新刷新整个控件片段或自己写JS增删节点,只要预先定义模板和符合其语法定义的属性即可.简单的说,我们只需要关注数据的存取. 一.引言 由于最近公司的系统需要改版,改版的新系统我打算使用KnockoutJs来制作Web前端.在做的过程中,遇到一个问题--如何使用KnockoutJs来完成分页的功能.在前一篇文章中并没有介绍使用KnockoutJs来实现分页,所以在这篇文章中,将补充用Knockou

  • KnockoutJS 3.X API 第四章之数据控制流component绑定

    一个例子 UI源码: <h4>First instance, without parameters</h4> <div data-bind='component: "message-editor"'></div> <h4>Second instance, passing parameters</h4> <div data-bind='component: { name: "message-edito

  • KnockoutJS 3.X API 第四章之表单value绑定

    Knockout是一个以数据模型(data model)为基础的能够帮助你创建富文本,响应显示和编辑用户界面的JavaScript类库.任何时候如果你的UI需要自动更新(比如:更新依赖于用户的行为或者外部数据源的改变),KO能够很简单的帮你实现并且很容易维护. 重要特性: 优雅的依赖追踪 - 不管任何时候你的数据模型更新,都会自动更新相应的内容. 声明式绑定 - 浅显易懂的方式将你的用户界面指定部分关联到你的数据模型上. 轻易可扩展 - 几行代码就可以实现自定义行为作为新的声明式绑定. 额外的好

  • BootstrapTable与KnockoutJS相结合实现增删改查功能【二】

    在上篇文章给大家介绍了BootstrapTable与KnockoutJS相结合实现增删改查功能[一],介绍了下knockout.js的一些基础用法.接下来通过本文继续给大家介绍.如果你也打算用ko去做项目,且看看吧! Bootstrap是一个前端框架,解放Web开发者的好东东,展现出的UI非常高端大气上档次,理论上可以不用写一行css.只要在标签中加上合适的属性即可. KnockoutJS是一个JavaScript实现的MVVM框架.非常棒.比如列表数据项增减后,不需要重新刷新整个控件片段或自己

  • KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定

    Knockout是一个以数据模型(data model)为基础的能够帮助你创建富文本,响应显示和编辑用户界面的JavaScript类库.任何时候如果你的UI需要自动更新(比如:更新依赖于用户的行为或者外部数据源的改变),KO能够很简单的帮你实现并且很容易维护. submit绑定目的 submit绑定即为提交绑定,通常用于form元素.这种绑定方式会打断默认的提交至服务器的操作.转而提交到你设定好的提交绑定回调函数中.如果要打破这个默认规则,只需要在回调函数中返回true即可. 例如: <form

  • KnockoutJS 3.X API 第四章之事件event绑定

    目的 event绑定即为事件绑定,即当触发相关DOM事件的时候回调函数.例如keypress,mouseover或者mouseout等 例如: Mouse over me 源码: <div> <div data-bind="event: { mouseover: enableDetails, mouseout: disableDetails }"> Mouse over me </div> <div data-bind="visibl

  • knockoutjs动态加载外部的file作为component中的template数据源的实现方法

    玩过knockoutjs的都知道,有一个强大的功能叫做component,而这个component有个牛逼的地方就是拥有自己的viewmodel和template,比如下面这样: ko.components.register('message-editor', { viewModel: function(){}, template:"" }); 很显然,viewmodel就是function函数区,而template就是模板区,然后通过register函数将component注册到kn

  • 如何动态加载外部Javascript文件

    最近在网上找到了一个可以动态加载js文件的js加载器,具体代码如下: JsLoader.js var MiniSite=new Object(); /** * 判断浏览器 */ MiniSite.Browser={ ie:/msie/.test(window.navigator.userAgent.toLowerCase()), moz:/gecko/.test(window.navigator.userAgent.toLowerCase()), opera:/opera/.test(windo

  • Vue动态加载图片在跨域时无法显示的问题及解决方法

    写在前面 小记,就简单写了 .问题:VUE开发时因为要访问后端的接口所以要配置请求转发,如果直接转发全部请求,那么VUE动态绑定的src也会转发到后端,因为图片在前端,所以会收到404 NOT FOUND的报错. 常规的请求转发 在vue-cli3内,直接编辑vue.config.js,如下: let proxyObj={}; proxyObj['/']={ ws:false, target:'http://localhost:8023',//后端地址 changeOrigin:true, pa

  • JS加载器如何动态加载外部js文件

    今天在网上找到了一个可以动态加载js文件的js加载器,具体代码如下: JsLoader.js var MiniSite=new Object(); /** * 判断浏览器 */ MiniSite.Browser={ ie:/msie/.test(window.navigator.userAgent.toLowerCase()), moz:/gecko/.test(window.navigator.userAgent.toLowerCase()), opera:/opera/.test(windo

  • 动态加载外部javascript文件的函数代码分享

    复制代码 代码如下: (function (clover) { clover.loadScript = function loadScript(url, callback) { var heads = document.getElementsByTagName('head'); if (heads.length == 0) { alert("page must have one head element"); } var head = heads[0]; var script = do

  • 动态加载Js代码到Head标签中的脚本

    复制代码 代码如下: HtmlGenericControl Include2 = new HtmlGenericControl("script"); Include2.Attributes.Add("type", "text/javascript"); Include2.InnerHtml = "alert('JavaScript in Page Header');"; this.Page.Header.Controls.Ad

  • 动态加载js和css(外部文件)

    复制代码 代码如下: // 动态加载外部js文件 var flag = true; if( flag ){ loadScript( "js/index.js" ); }; function loadScript( url ){ var script = document.createElement( "script" ); script.type = "type/javascipt"; script.src = url; document.get

  • JavaScript动态加载重复绑定问题

    前言 在添加一条数据时,使用动态加载显示在界面,后来发现一个严重的bug,拿我做的这个便签为例,当我添加一条数据后,然后点击删除的时候,提示是否删除,如下图: 但是当我添加两条以上的数据时,删除第几条就会提示几次是否确认删除. 经过排查,终于发现问题所在. 正文 当动态添加内容后,通常会写上添加的这些div中需要用到的事件,比如click事件/chang事件等.还拿我的删除事件为例,由于删除事件必须写在添加便签的事件下,所以当添加第一条数据时,绑定一次,添加第二条时,绑定一次,添加第n条数据时,

  • springBoot如何动态加载资源文件

    目录 springBoot动态加载资源文件 构造DynamicLoadPropertySource 添加到Enviroment springBoot静态资源动态加载 举例说明 springBoot动态加载资源文件 在实际项目中资源信息如果能够动态获取在修改线上产品配置时极其方便,下面来展示一个加载动态获取资源的案例,而不是加载写死的properties文件信息. 首先构造PropertySource,然后将其添加到Enviroment中. 构造DynamicLoadPropertySource

  • Angular.js实现动态加载组件详解

    前言 有时候需要根据URL来渲染不同组件,我所指的是在同一个URL地址中根据参数的变化显示不同的组件:这是利用Angular动态加载组件完成的,同时也会设法让这部分动态组件也支持AOT. 动态加载组件 下面以一个Step组件为示例,完成一个3个步骤的示例展示,并且可以通过URL user?step=step-one 的变化显示第N个步骤的内容. 1.resolveComponentFactory 首先,还是需要先创建动态加载组件模块. import { Component, Input, Vie

随机推荐