JQuery模板 :(六)JsViews - 基于JsRender并具有动态绑定功能的模板
一、什么是JsViews:
1) 下一代MVVM框架,兼具MVVM的特性和JavaScript的特性,使JsRender模板更加快捷和简单。
2) JsViews框架引入了声明式的数据绑定到JsRender Template,支持MVVM和MVP(自定义标签控制)。
3)是一个用于数据绑定的单page的app。
4)JsViews提供了动态绑定的功能,构建与JsRender模板之上。让JsRender template动起来。
二、简单的例子:
1. 使用template.link()
<!DOCTYPE html>
<html>
<head>
<link href="http://www.jsviews.com/samples/resources/css/samples.css" rel="stylesheet"/>
<script src="../jquery/jquery-2.0.3.js"></script>
<script src="../jsviews/jsviews.js"></script>
</head>
<body>
<table><tbody id="peopleList"></tbody></table>
<script id="peopleTmpl" type="text/x-jsrender">
<tr><td>
<ul>
{{for p}}
<li>
{{:name}}
</li>
{{/for}}
</ul>
</td></tr>
</script>
<script>
var myTemplate = $.templates("#peopleTmpl");
var people = [
{
name: "JoshWang"
},
{
name: "WangSheng"
}
];
var app = {
p: people
};
myTemplate.link("#peopleList", app);
</script>
</body>
</html>说明:很容易看出这个例子和之前的JsRender sample的例子是极其类似的。唯一不同地方是,之前用于渲染template数据的两行代码现在只有一行代码即可。
var html = myTemplate.render(app);
$("#peopleList").html(html);myTemplate.link("#peopleList", app);第一个参数表示的是元素的container(此处是一个table)第二个参数表示的是用于渲染的数据。
2. Data-linking
在JsViews中使用data-linking来进行数据绑定。但是涉及到一些特殊的应用的时候,就需要使用obserable的数组和对象了。
例如,如果现在有一个对象,并且赋予其中一个属性 一个新的值,显然这里没有相关的事件来通知其他的code去更新该object。同样地,修改一个数组也不会有相关的事件通知其他的code做相关的更新。
例子:(显示地修改对象和数组)
$("#addBtn").on("click", function(){
$.observable(people).insert(people.length, {name: "name"});
})实例1:可视的数组和对象(可视的意思是该对象或者数组发生变化时,template中与之绑定的数据也会自动更新)
<!DOCTYPE html>
<html>
<head>
<link href="http://www.jsviews.com/samples/resources/css/samples.css" rel="stylesheet"/>
<script src="../jquery/jquery-2.0.3.js"></script>
<script src="../jsviews/jsviews.js"></script>
</head>
<body>
<table><tbody id="peopleList"></tbody></table>
<script id="peopleTmpl" type="text/x-jsrender">
<tr><td>
<button id="addBtn">Add</button>
</td></tr>
{^{for p}}
<tr><td>
{{:name}}
</td></tr>
{{/for}}
</script>
<script>
var myTemplate = $.templates("#peopleTmpl");
var people = [
{
name: "JoshWang"
},
{
name: "WangSheng"
}
];
var app = {
p: people
};
var html = myTemplate.link("#peopleList", app);
$("#addBtn").on("click", function(){
$.observable(people).insert(people.length, {name: "newName"});
})
</script>
</body>
</html>代码说明:点击Add按钮,会添加一条记录到Array中,然后该template就会自动更新并显示出新加的这一行。使用的code是:$.observable(people).insert(people.length, {name: "name"});
但是需要注意的是这个template和之前的template所有不同,{^{for ...}}。如果去掉^,然后重新点击Add Button后,你会发现没有任何的变化。这是因为任何的常规的JsRender 的标签:{{someTag...}},无论是内置的还是自定义的,都可以通过添加^变成一个数据绑定标签:{^{some Tag...}}.换句话说,这样的标签就变成了动态的标签,当无论何时需要的哦时候,都会自动的的去重新渲染它(如果相关的数据发生变化时)。
简言之:^这样的标签是动态的可用于动态绑定的标签,而没有^的标签是死的标签,不能用于数据绑定。
实例2: 可视的变化:属性变化。(可视表示属性发生变化时,template中绑定的内容也会自动刷新)
<!DOCTYPE html>
<html>
<head>
<link href="http://www.jsviews.com/samples/resources/css/samples.css" rel="stylesheet"/>
<script src="../jquery/jquery-2.0.3.js"></script>
<script src="../jsviews/jsviews.js"></script>
</head>
<body>
<table><tbody id="peopleList"></tbody></table>
<script id="peopleTmpl" type="text/x-jsrender">
<tr><td colspan="2">
<button id="addBtn">Add</button>
</td></tr>
{^{for p}}
<tr>
<td>{^{:name}}</td>
<td>
<button class="changeBtn">Change</button>
</td>
</tr>
{{/for}}
</script>
<script>
var myTemplate = $.templates("#peopleTmpl");
var people = [
{
name: "JoshWang"
},
{
name: "WangSheng"
}
];
var app = {
p: people
};
var counter = 1;
myTemplate.link("#peopleList", app);
$("#addBtn").on("click", function() {
$.observable(people).insert(people.length, {name: "name"});
})
$("#peopleList").on("click", ".changeBtn", function() {
var dataItem = $.view(this).data;
$.observable(dataItem).setProperty("name", dataItem.name + counter++);
})
</script>
</body>
</html>代码解读:
1) $.observable(myObject)可以获取该对象的可视形式,即使该对象变成可视对象,即该对象的修改会引起和他绑定的template中相关内容的自动更新。
2)var dataItem = $.view(this).data 用于获取当前需要修改的object。
3.基于标签的”data-link"
<td data-link="name"></td>
这和上一个例子中的:
<td>{^{:name}}</td>具有相关的效果。
4. 双向的数据绑定:
<td data-link="name"></td> <td> <input data-link="name"/> </td>
<input>和<td>都是数据绑定的,这使得不需要向实例2中那样添加一个propertyChange(属性变化)来使得template同时发生变化。
<!DOCTYPE html>
<html>
<head>
<link href="http://www.jsviews.com/samples/resources/css/samples.css" rel="stylesheet"/>
<script src="../jquery/jquery-2.0.3.js"></script>
<script src="../jsviews/jsviews.js"></script>
</head>
<body>
<table><tbody id="peopleList"></tbody></table>
<script id="peopleTmpl" type="text/x-jsrender">
<tr><td colspan="2">
<button id="addBtn">Add</button>
</td></tr>
{^{for people}}
<tr>
<td data-link="name"></td>
<td>
<input data-link="name"/>
</td>
</tr>
{{/for}}
</script>
<script>
var myTemplate = $.templates("#peopleTmpl");
var people = [
{
name: "JoshWang"
},
{
name: "WangSheng"
}
];
var app = {
people: people
};
var counter = 1;
myTemplate.link("#peopleList", app);
$("#addBtn").on("click", function() {
$.observable(people).insert(people.length, {name: "name"});
})
</script>
</body>
</html>5. 更加完整的例子:(在Select标签上使用数据绑定)
<!DOCTYPE html>
<html>
<head>
<link href="http://www.jsviews.com/samples/resources/css/samples.css" rel="stylesheet"/>
<script src="../jquery/jquery-2.0.3.js"></script>
<script src="../jsviews/jsviews.js"></script>
</head>
<body>
<table><tbody id="peopleList"></tbody></table>
<script id="peopleTmpl" type="text/x-jsrender">
<tr><td>
<button id="addBtn">Add</button>
<button id="removeBtn" data-link="disabled{:selectedID === '0'}">Remove</button>
</td></tr>
<tr><td>
<select data-link="selectedID" size="5">
<option value="0">Choose a person to edit</option>
{^{for people}}
<option data-link="{:name} value{:ID} selected{:ID === ~root.selectedID}"></option>
{{/for}}
</select>
</td></tr>
<tr><td>
<label>Name:<input data-link="{:selected().name:} disabled{:selectedID === '0'}" /></label>
<label>Nickname:<input data-link="{:selected().nickname:} disabled{:selectedID === '0'}" /></label>
</td></tr>
<tr><td class="center">
{^{for selected()}}
{^{:name}}
{^{if nickname}}
( {^{:nickname}} )
{{/if}}
{{/for}}
</td></tr>
</script>
<script>
var myTemplate = $.templates("#peopleTmpl");
var people = [
{
ID: "Ad0",
name: "JoshWang"
},
{
ID: "Ro0",
name: "WangSheng",
nickname: "Jack"
}
];
var counter = 1;
var app = {
people: people,
selectedID: people[1].ID,
selected: function() {
for (var i=0; i<people.length; i++) {
if (people[i].ID === this.selectedID) {
return people[i];
}
}
return {};
}
};
app.selected.depends = "selectedID";
// Data-link details container to people, using the peopleTmpl template
myTemplate.link("#peopleList", app);
$("#addBtn").on("click", function(){
var newID = "new" + counter++;
$.observable(people).insert(people.length, {ID: newID, name: "name"});
$.observable(app).setProperty("selectedID", newID);
})
$("#removeBtn").on("click", function(){
$.observable(people).remove($.inArray(app.selected(), people));
$.observable(app).setProperty("selectedID", "0");
})
</script>
</body>
</html>运行效果图:

三、综合实例
1. 动态绑定:所谓动态绑定就是当数据源发生变化时,与数据源绑定的组件也会动态的刷新。
<!DOCTYPE html>
<html>
<head>
<link href="http://www.jsviews.com/samples/resources/css/samples.css" rel="stylesheet"/>
<script src="../jquery/jquery-2.0.3.js"></script>
<script src="../jsviews/jsviews.js"></script>
</head>
<body>
<div id="result"></div>
<script id="theTmpl" type="text/x-jsrender">
<div>
Edit: <input type="checkbox" data-link="editable"/>
<em>Name:</em> {^{:name}}
{^{if showNickname && nickname}}
(Goes by <em data-link="nickname"></em>)
{{/if}}
{^{if editable}}
<div>
<input data-link="name"/>
<input data-link="nickname"/>
<input type="checkbox" data-link="showNickname"/>
</div>
{{/if}}
</div>
</script>
<script>
var data = [
{
"name": "JoshWang",
"nickname": "DW",
"showNickname": true
},
{
"name": "Susan",
"nickname": "Sue",
"showNickname": false
}
];
var template = $.templates("#theTmpl");
template.link("#result", data);
</script>
</body>
</html>代码解读
1){^{name}} ... {^{if showNickname && nickname}}.这些标签是数据绑定标签,当与之关联的数据发生变化时,在template中相关的数据单元也会自动的发生变化。
2)将{{if...}}改成{^{if...}}同样是数据绑定。当关联的数据发生变化时,整个template部分的内容会自动的移除或者是重新插入。
3)<em data-link="nickname">: 同样可使用element-based来做数据绑定,这里表示<em>标签的文本内容会自动的绑定到nickName的值。
4) <input data-link="name"/>:这里 input会一双重绑定的方式自动的绑定到相关联数据的name属性。在这里,当修改input text box中的值的时候,相关的关联数据也会自动的更新,二该template的其他data-linked到同样属性(name)的部分也会立即自动的更新。