b-template
的值的字段在templates
里面定義. 注意: 子集的內(nèi)容必須有標(biāo)簽包住. 例如模板里面的li
標(biāo)簽.
var bs = bui.store({
scope: "page",
data: {
list: ["我是列表1","我是列表2"],
},
templates: {
tplList: function (data) {
let html = "";
data.forEach(function (item,i) {
html += `<li class="bui-btn">${item}</li>`;
})
return html;
}
}
})
html:
<ul b-template="page.tplList(page.list)" class="bui-list"></ul>
var bs = bui.store({
scope: "page",
data: {
obj: {
title: "我的對(duì)象的標(biāo)題",
content: "<p>我是內(nèi)容,支持html</p><p>我是內(nèi)容,支持html</p>"
}
},
templates: {
tplObject: function (data) {
let html = "";
for( let key in data ){
html += `<div class="bui-btn" >${data[key]}</div>`;
}
return html;
}
}
})
html:
<div b-template="page.tplObject(page.obj)"></div>
如果對(duì)象需要?jiǎng)討B(tài)聯(lián)動(dòng), 有2種方法:
方法1: obj
為數(shù)據(jù)源
// 改變數(shù)據(jù)
bs.obj.title = "我的對(duì)象的標(biāo)題2";
// 告訴使用obj的模板,數(shù)據(jù)變更需要重新渲染
bs.trigger("obj",{value:bs.obj});
方法2: obj
為數(shù)據(jù)源
// 改變數(shù)據(jù)
bs.obj.title = "我的對(duì)象的標(biāo)題2"
// 告訴使用obj的模板,數(shù)據(jù)變更需要重新渲染
bs.set("obj",bs.obj);
方法1 跟 方法2的區(qū)別在于, 方法1只是變更并重新觸發(fā)模板渲染, 方法2, 會(huì)對(duì)數(shù)據(jù)的所有鍵值重新賦值并觸發(fā)模板渲染.
html:
<div >
<div b-text="page.obj.title"></div>
<div b-html="page.obj.content"></div>
</div>
支持?jǐn)?shù)據(jù)是一個(gè)對(duì)象, 那就可以更好的設(shè)計(jì)這個(gè)數(shù)據(jù)了, 但不建議把數(shù)據(jù)層級(jí)設(shè)計(jì)得太深.
var bs = bui.store({
scope: "page",
data: {
objList: {
title: "我是標(biāo)題",
data: ["我是復(fù)雜數(shù)據(jù)列表1"]
}
},
templates: {
tplObjectList: function (data,e) {
var html = "";
data.forEach(function (item,i) {
html += `<li class="bui-btn">${item}</li>`;
})
return html;
}
}
})
<h2 b-text="page.objList.title"></h2>
<ul b-template="page.tplObjectList(page.objList.data)" class="bui-list"></ul>
如果
h2
是在ul
里面, 那么默認(rèn)第一次渲染數(shù)據(jù),h2
就會(huì)被替換, 這時(shí)可以通過(guò)b-command
屬性,告訴模板第一次渲染采用什么方式. :) 當(dāng)然這里ul
標(biāo)簽里面放h2
標(biāo)簽是不符合w3c標(biāo)準(zhǔn)的. 我們改成li
標(biāo)簽.
<ul b-template="page.tplObjectList(page.objList.data)" b-command="append" class="bui-list">
<li b-text="page.objList.title"></li>
</ul>
如果 ul 的子集不止有l(wèi)i標(biāo)簽元素?
b-children
就可以派上用場(chǎng), 代表子集的重復(fù)元素是哪個(gè)選擇器?
比方:
<ul b-template="page.tplObjectList(page.objList.data)" b-children=".bui-btn" class="bui-list">
</ul>
這個(gè)生成的模板可能是這樣的. 如果你使用 bui.array.set
修改數(shù)據(jù)的時(shí)候,變成新增, 這個(gè)時(shí)候你就要懷疑是不是需要設(shè)置 b-children
.
<ul b-template="page.tplObjectList(page.objList.data)" b-children=".bui-btn" class="bui-list">
<li class="section-title">我是二級(jí)標(biāo)題</li>
<li class="bui-btn">我是內(nèi)容0,索引0</li>
<li class="section-title">我是二級(jí)標(biāo)題</li>
<li class="bui-btn">我是內(nèi)容1,索引1</li>
<li class="section-title">我是二級(jí)標(biāo)題</li>
<li class="bui-btn">我是內(nèi)容2,索引2</li>
</ul>
通過(guò)
b-template
的綁定, 我們可以通過(guò)操作數(shù)組,便能得到頁(yè)面的及時(shí)響應(yīng).
var bs = bui.store({
scope: "page",
data: {
list: ["我是列表1","我是列表2"],
},
templates: {
tplList: function (data) {
let html = "";
data.forEach(function (item,i) {
html += `<li class="bui-btn">${item}</li>`;
})
return html;
}
}
})
html:
<ul b-template="page.tplList(page.list)" class="bui-list"></ul>
這樣綁定以后, 通過(guò)腳本操控
bs.list.push("我是列表3")
, 頁(yè)面便能及時(shí)渲染新的數(shù)據(jù).
不過(guò)并非數(shù)組的所有操作都能得到及時(shí)響應(yīng), 目前我們可以監(jiān)聽(tīng)到以下幾種方法:
push
在后面增加數(shù)據(jù)unshift
在前面增加數(shù)據(jù)shift
刪除第1條數(shù)據(jù)pop
刪除最后一條數(shù)據(jù)splice
刪除或者插入新的數(shù)據(jù), 具體可以查看數(shù)組的splice用法sort
排序reverse
反序length
獲取長(zhǎng)度為了更方便的操作數(shù)據(jù)視圖, 我們還提供了幾個(gè)命令式的方法, 可以方便的對(duì)數(shù)組進(jìn)行操作響應(yīng). 具體可以查看對(duì)應(yīng)的 bui.array API 使用說(shuō)明, 在綜合案例里面, 我們會(huì)頻繁的用到.
bui.array.empty
清空數(shù)組,并觸發(fā)第1個(gè)數(shù)組的視圖變更bui.array.replace
替換數(shù)組,并觸發(fā)第1個(gè)數(shù)組的視圖變更bui.array.merge
合并數(shù)組,并觸發(fā)第1個(gè)數(shù)組的視圖變更bui.array.set
修改數(shù)組的某個(gè)值,支持對(duì)象bui.array.delete
刪除數(shù)組的某個(gè)值,支持對(duì)象值得注意的是, 如果數(shù)組里面是一個(gè)對(duì)象, 對(duì)象的某個(gè)字段變更是不會(huì)反饋到視圖的, 這種時(shí)候就可以使用
bui.array.set
來(lái)替換整條數(shù)據(jù), 達(dá)到刷新視圖的目的. 這個(gè)可以查看 綜合案例章節(jié)的多選聯(lián)動(dòng)的setStatus
方法, 會(huì)修改到數(shù)組對(duì)象的狀態(tài).
1.5.3 以后, 上面那些方法, 可以有更方便的使用方式
, 比方:
1.5.4修正: 只有通過(guò) bui.store 初始化劫持的數(shù)組,才會(huì)有 $方法操作
1.清空數(shù)組 [].$empty()
var bs = bui.store({
data: {
arr:["hello","bui","hi","easybui"]
}
})
bui.array.empty( bs.arr );
// 1.5.4 版本以后可以這樣
bs.arr.$empty();
2.替換數(shù)組 [].$replace()
var bs = bui.store({
data: {
arr:["hello","bui","hi","easybui"]
}
})
bui.array.replace( bs.arr, ["new","bui"]);
// 1.5.4 版本以后可以這樣
bs.arr.$replace(["new","bui"]);
3.合并數(shù)組 [].$merge()
var bs = bui.store({
data: {
arr:["hello","bui","hi","easybui"]
}
})
bui.array.merge( bs.arr, ["new","bui"]);
// 1.5.4 版本以后可以這樣
bs.arr.$merge(["new","bui"],["easy"]);
4.修改數(shù)組 [].$set()
// 例子1: 修改第幾個(gè)
var bs = bui.store({
data: {
arr:["hello","bui","easybui"]
}
})
bui.array.set( bs.arr, 1, "new hi");
// ["hello","new hi","easybui"]
// 1.5.4 版本以后可以這樣
bs.arr.$set(1, "new hi");
// arr 結(jié)果: ["hello","new hi","easybui"]
// 例子2: 修改值等于 bui 為新值 new bui
var bs = bui.store({
data: {
arr:["hello","bui","easybui"]
}
})
bui.array.set( bs.arr, "bui", "new bui");
// ["hello","new bui","easybui"]
// 1.5.4 版本以后可以這樣
bs.arr.$set("bui", "new bui");
// arr 結(jié)果: ["hello","new bui","easybui"]
// 例子3: 修改對(duì)象值
var bs = bui.store({
data: {
arr:[{name:"hello"},{name:"hi"},{name:"easybui"}]
}
})
bui.array.set( bs.arr, 1, {name:"new hi"} );
// [{name:"hello"},{name:"new hi"},{name:"easybui"}]
// 1.5.4 版本以后可以這樣
bs.arr.$set(1, {name:"new hi"});
// arr 結(jié)果: [{name:"hello"},{name:"new hi"},{name:"easybui"}]
// 例子4: 修改對(duì)象某個(gè)字段值, 需要傳多一個(gè)唯一值的字段名
var bs = bui.store({
data: {
arr:[{name:"hello"},{name:"hi"},{name:"easybui"}]
}
})
// 1.5.4 版本以后可以這樣
// 單獨(dú)修改某個(gè)值
bs.arr.$set("hello", "hi bui", "name");
// 修改整個(gè)對(duì)象,不同的key值則會(huì)一起合并過(guò)去
bs.arr.$set("hi", {name:"new hi"}, "name");
// arr 結(jié)果: [{name:"hello"},{name:"new hi"},{name:"easybui"}]
5.刪除數(shù)據(jù)并觸發(fā)視圖更新
//例子1: 刪除值或索引:
var bs = bui.store({
data: {
arr:["hello","bui","hi","bui"]
}
})
bui.array.delete(bs.arr , "bui" );
// 1.5.4 版本以后可以這樣
bs.arr.$delete("hi");
// arr 結(jié)果: ["hello","hi"]
// 例子2: 刪除值在哪個(gè)字段:
var bs = bui.store({
data: {
arr:[{ "id":1,value:"hello"},{ "id":2,value:"bui"}]
}
})
bui.array.delete( bs.arr, "bui", "value" );
// 1.5.3 版本以后可以這樣
bs.arr.$delete("bui", "value");
// arr 結(jié)果: [{ "id":1,value:"hello"}]
再來(lái)一個(gè)交互類(lèi)的模板, 為了代碼更加清晰易懂,樣式類(lèi)的屬性都去掉.
var bs = bui.store({
scope: "page",
data: {
citysCheck: ["廣州","深圳"],
citys: ["廣州","深圳","上海","北京"],
},
templates: {
tplListCheck: function (data) {
var html = "";
data.forEach(function (item,i) {
html += `<li class="bui-btn"><label><input type="checkbox" name="city" value="${item}" b-model="page.citysCheck">${item}</label></li>`;
})
return html;
}
}
})
當(dāng)前選中: <b b-text="page.citysCheck"></b>
<ul id="cityList" b-template="page.tplListCheck(page.citys)"></ul>
這個(gè)模板用到
b-model
屬性, 這在一開(kāi)始有數(shù)據(jù)的時(shí)候, 渲染是正確的, 當(dāng)數(shù)據(jù)是異步增加進(jìn)來(lái)以后, 這個(gè)數(shù)據(jù)并沒(méi)有選中狀態(tài). 那要如何處理呢?
var bs = bui.store({
scope: "page",
data: {
citysCheck: [],
citys: [],
},
templates: {
tplListCheck: function (data) {
let _self = this;
let html = "";
data.forEach(function (item,i) {
// 通過(guò)比對(duì),增加選中狀態(tài)
let hasCheck = bui.array.compare(item,_self.citysCheck);
let checked = hasCheck ? "checked" : "";
html += `<li class="bui-btn"><label><input type="checkbox" name="city" value="${item}" b-model="page.citysCheck" ${checked}>${item}</label></li>`;
})
return html;
}
},
mounted: function () {
// 模擬數(shù)據(jù)動(dòng)態(tài)改變
setTimeout(()=>{
// 方法1:
this.citysCheck.push("廣州","深圳")
this.citys.push("廣州","深圳","上海","北京");
// 方法2:
// bui.array.merge(this.citysCheck,["廣州","深圳"])
// bui.array.merge(this.citys,["廣州","深圳","上海","北京"])
},1000)
}
})
這里其實(shí)還有一種辦法, 通過(guò)使用
this.oneTick
方法綁定citys
的數(shù)據(jù)更新,并且視圖已經(jīng)渲染完成以后, 執(zhí)行多一次解析行為屬性. 這個(gè)compile
要慎用, 多次調(diào)用會(huì)增加多個(gè)重復(fù)的回調(diào), 造成性能的損耗.
mounted: function () {
// 模擬數(shù)據(jù)動(dòng)態(tài)改變
setTimeout(()=>{
// 通過(guò)監(jiān)聽(tīng) citys 的數(shù)據(jù)變更并且視圖渲染完成以后, 增加數(shù)據(jù)的解析, 這樣就不用在模板里面做數(shù)據(jù)比對(duì)處理了.
// 必須在數(shù)據(jù)更新之前
this.oneTick("citys",function () {
this.compile("#cityList")
})
// 數(shù)據(jù)更新
this.citysCheck.push("廣州","深圳")
this.citys.push("廣州","深圳","上海","北京");
},1000)
}
我們的頁(yè)面只有干凈的綁定, 其它都在模板的方法里面處理邏輯, 正常ES6模板其實(shí)已經(jīng)能夠很好的滿足我們的需求了, 不過(guò)如果你習(xí)慣用第三方模板的話, 你也可以使用, 這里以
artTemplate
為例, 需要在首頁(yè)引入這個(gè)模板的js文件.
var bs = bui.store({
scope: "page",
data: {
list: ["我是列表1","我是列表2"],
},
templates: {
artTplList: function (data,e) {
var html = template("tpl-list",{ listData: data});
return html;
}
}
})
<ul b-template="page.artTplList(page.list)" class="bui-list"></ul>
<script id="tpl-list" type="text/html">
{{each listData item index}}
<li class="bui-btn" href="pages/ui_controls/bui.store.html" >{{item}}</li>
{{/each}}
</script>
更多建議: