mvc-5视图和模版
动态渲染视图
- 当待渲染的视图内容不多的时候,可以将视图元素放在控制器或者状态里
var views = document.getElementById("views");
views.innerHTML = ""; //将元素内容清空
var container = document.createElement("div");
container.id = "user"; //设置id
var name = document.createElement("span");
name.innerHTML = data.name;
container.appendChild(name);
views.appendChild(container);
//或使用jquery
$("#views").empty();
var container = $("<div/>").attr({id: "user"});
var name = $("<span/>").text(data.name);
$("#views").append(container.append(name));
- 此外也可以将静态页面包含再页面中,再必要时候显示或隐藏;
模版
js模版的核心概念是,将包含模版变量的HTML片段和JavaScript对象做合并,把模版变量替换为对象中的属性值, 以下都以jquery.tmpl模版为例
<script type="text/javascript">
var object = {
url: "https://www.google.com/",
getName: function () {
return "testName";
}
};
var tmpl = '<li><a href="${url}">${getName()}</a></li>';
var elem = jQuery.tmpl(tmpl, object);
$("body").append(elem);
</script>
//
<script id="tmpl" type="text/template">
<li><a href="${url}">${getName()}</a></li>
</script>
<script type="text/javascript">
var object = {
url: "https://www.google.com/",
getName: function () {
return "testName";
}
};
var elem = $("#tmpl").tmpl(object);
elem.appendTo($("body"));
</script>
- 一些高级功能
<script type="text/template" id="tmpl">
{{if url}}
${url}
{{/if}}
{{if messages.length}}
<ul>
{{each messages}}
<li>${$index + 1}: <em>${$value}</em></li>
{{/each}}
{{else}}
no messages
{{/if}}
</script>
<script type="text/javascript">
var object = {
url: "https://www.google.com/",
messages: ['one', 'two']
};
var elem = $("#tmpl").tmpl(object);
$("body").append(elem);
</script>
可以用$value
变量来访问当前正被遍历的值;数组元素的索引可以使用$index
变量来输出
模版helper
有时再视图内部使用通用helper函数,比如格式化一个日期或数字;为了保持mvc架构,最好的方法应该是将它们抽象出来,并用命名空间进行管理,而不是直接将函数掺进视图中,这样才能保持逻辑和视图之间的解偶
//替换一段纯文本中的<a></a>标签里的链接
<script type="text/tamplate" id="tmpl">
${helper.autoLink(this.data)} //这里data指代tmpl()方法传入的数据;
</script>
<script type="text/javascript">
var helper = {};
helper.autoLink = function(data) {
var re = /((http|https|ftp):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>]))/g;
console.log(data);
return (data.replace(re, '<a target="_blank" href="$1">$1</a>'));
};
var elem = $("#tmpl").tmpl("https://github.com/maccman/jquery.tmpl");
$("body").append(elem);
</script>
模版存储
包括
- JavaScript中以行内形式存储;//违背了MVC架构原则,不推荐
- 在自定义script标签里以行内形式存储; //推荐,通过Id来获取模版引用;浏览器不会对它们进行渲染而仅解析为内容文本
- 远处加载; //注意速度问题
- 在HTML中以行内形式存储
<script type="text/tamplate" id="tmpl">
<span>${getName()}</span>
</script>
<script type="text/javascript">
var data = {
getName: function() {return "Bob"}
};
var element = $("#tmpl").tmpl(data);
element.appendTo($("body"));
</script>
- 在程序后台,jquery.tmpl会确保模版一旦生成后,解析后的模版就能被缓存住,而不必2次解析;
- 首先根据内容生成元素,然后将它追加到页面中,这种方式性能比操作已经追加至页面的元素更好,这是一种最佳实践
- 实际上运用一些“依赖管理工具”会更加简洁,如RequireJS
绑定
绑定将视图元素和js对象(通常是模型)挂接在一起;当js对象发生改变时,视图会根据新修改后的对象做适时更新
为了将js对象和视图绑定在一起,需要设置一个回调函数,当对象的熟悉发生改变时发送一个更新视图的通知
var addChange = function (ob) {
ob.change = function(cb) {
if(cb) {
if(!this._change) this._change = [];
this._change.push(cb);
} else {
if(!this._change) return;
for(var i = 0, len = this._change.length; i < len; i++) {
this._change[i].apply(this);
}
}
}
}
var object = {};
object.name = 'Foo';
addChange(object);
object.change(function() {
console.log("Changed!", this);
//添加更新视图的代码
});
object.change();
object.name = "Bar";
object.change();
给这个对象添加了change()回调, 这样就可以执行绑定和触发change事件
模型中的事件绑定
<script type="text/javascript" charset="utf-8">
var User = function(name){
this.name = name;
};
User.records = []
User.bind = function(ev, callback) {
var calls = this._callbacks || (this._callbacks = {});
(this._callbacks[ev] || (this._callbacks[ev] = [])).push(callback);
};
User.trigger = function(ev) {
var list, calls, i, l;
if (!(calls = this._callbacks)) return this;
if (!(list = this._callbacks[ev])) return this;
jQuery.each(list, function(){ this() })
};
User.create = function(name){
this.records.push(new this(name));
this.trigger("change")
};
jQuery(function($){
User.bind("change", function(){
var template = $("#userTmpl").tmpl(User.records);
$("#users").empty();
$("#users").append(template);
});
User.create("First one");
setTimeout(function(){
User.create("Another one");
}, 2000);
});
</script>
</head>
<body>
<script id="userTmpl" type="text/x-jquery-tmpl">
<li>${name}</li>
</script>
<ul id="users">
</ul>
</body>