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