NView数据绑定
除了标准字符串模式的文本、属性设置外,NView模板支持将NView实例数据绑定至NView控件上。
插值
NView模板的文本、属性插值方式相同,均使用大括号({})表示当前为Javascript表达式,不是直接字符串赋值,如下为一个简单示例:
<template>
<nviews cacheMaxAge="86400">
<nview id="nview1" style="position:static;top:200px;height:50px;">
<Font>{data.product_name}</Font>
</nview>
</nviews>
</template>
<script>
module.exports = {
data: {
product_name:'产品名称'
}
};
</script>
NView模板中的Javascript表达式,要求必须是单个表达式或JSON对象,如下都是合法的:
<nview id="nview1" style={{
//这里是json对象
position:"static",
top:data.top
}}>
<Font>{data.rem * 17}</Font>
<img id="img1" style={{
//三元表达式
width:data.full?"100%":"80%"
}}>
</nview>
备注:两个大括号{{}}的含义,外层大括号{}表示接下来为Javascript运算符,内层大括号{}表示当前为一个JSON对象。
下面的例子则不生效,因为他们是语句,而不是表达式
<font>{data.rem = 10}</font>
数据源
NView模板可以绑定JavaScript动态计算的数据,数据的提供主要有两种方式:
- 直接通过data属性提供默认值,这种方式适用于数据相对固定,跟具体业务无关的场景,比如设置界面、开发商等
- 在init属性中,编写JavaScript代码,根据业务场景动态计算(请求)数据
data属性
默认数据可直接在data属性中提供,data支持Object、Function两种方式,例如:
<script>
module.exports = {
data: {
vendor:'DCloud',
city:'北京'
}
};
</script>
下面是Function示例,返回值要求是Object类型;Function适合需要简单计算的场景,比如根据屏幕分辨率动态计算文字大小、宽高等场景:
<script>
module.exports = {
data: function() {
return {
fontSize:window.screen.width > 360 ? "17px" : "15px",//动态计算
vendor:'DCloud'
}
}
};
</script>
init属性
跟业务相关的数据,可以在init中通过JavaScript编程实现,使用方式如下:
<script>
module.exports = {
data: {
//默认数据
},
init: function(url) {
//url为新开webview加载的地址,可以通过url分析出部分业务参数
//TODO 获取数据,存储为newData
var newData = {};
...
//必需:重新设置data
this.setData(newData);
}
};
</script>
动态计算NView数据,通常有三种场景:
- 通过页面url地址,分析出所需业务参数,适合页面url和业务数据有明确对应关系的场景
- 通过前页获取数据,比如列表页已经显示了商品的名称,则详情页可以直接复用列表页的商品名称数据
- 通过ajax请求获取数据,这样可以在Document加载完成之前提前发起请求并渲染
如上三种方式可混合使用,每次调用setData()方法,都会覆盖之前的数据(merge覆盖,非完全替换),如下是示例:
<script>
module.exports = {
data: {
vendor:'DCloud',
author:'CHB',
product:{
name:'wap2app'
}
},
init: function(url) {
var newData = {
author:'FXY',
product:{
description:'基于M站的强化方案'
}
};
//必需:重新设置data
this.setData(newData);
}
};
</script>
如上代码运行后,最终的模板数据为:
{
vendor:'DCloud',//保留
author:'FXY',//替换
product:{
name:'wap2app',//保留
description:'基于M站的强化方案'//新增
}
}
通过url分析业务数据
这种模式适合页面url和业务参数有明确对应关系的场景,比如页面地址为http://www.example.com/detail/%id%,该页面上图片轮播地址固定为:
http://www.example.com/images/%id%/1.png
http://www.example.com/images/%id%/2.png
http://www.example.com/images/%id%/3.png
我们可以通过分析页面url,解析出id参数,然后拼接轮播组件图片源地址,如下是一个示例代码:
<template>
<nviews cachemaxage="86400">
<nview id="nvew2" style="height:200px;">
<!--图片轮播-->
<imageslider images={data.imgList}></imageslider>
</nview>
</nviews>
</template>
<script>
module.exports = {
data: {
//默认数据
},
init: function(url) {
//页面url地址为http://www.example.com/detail/%id%
//分析页面id
var id = url.substring(url.lastIndexOf("/")+1)
var newData = {};
var list = new Array();
//循环,构建原生轮播图片源信息
for (var i = 1; i <= 3; i++) {
var item = {};
//图片源地址
item.src = "http://www.example.com/images/" + id + "/" + i +".png";
item.width = "100%";
list.push(item);
}
//设置轮播组件信息
newData.imgList = list;
//重新设置data
this.setData(newData);
}
};
</script>
复用前页数据
下图是一个示例,从列表打开详情(列表页就是前页),详情页的部分数据和列表页相同(如商品图片、标题、价格等),此时就可以复用列表页的数据,提前渲染:
复用前页数据的思路:
- 用户在前页点击时,将可复用信息存储到本地缓存中
- 在新页面创建后,从本地缓存中读取数据并渲染到NView中
我们以列表打开详情页,详情页使用NView加速渲染为例,演示如何实现复用前页(列表页)数据。
前页存储本地缓存
用户点击时存储数据的代码,建议在M站编写,也可以在HBuilder客户端编写,然后通过appendJS的方式插入到原站。如下是一个示例代码:
假设前页列表HTML代码如下:
<!-- 列表开始 -->
<div id="list">
<!-- 第一个列表项 -->
<div class="item">
<img src="http://www.example.com/img/1.png" alt="" />
<p class="title">Item 1</p>
</div>
<!-- 第二个列表项 -->
<div class="item">
<img src="http://www.example.com/img/2.png" alt="" />
<p class="title">Item 2</p>
</div>
</div>
<!-- 列表结束 -->
我们可以增加如下JS代码,当用户点击列表项时,将列表项数据缓存到plus.storage中,示例如下:
(function() {
//非5+引擎环境,退出
if(navigator.userAgent.indexOf("Html5Plus") == -1) {
return false;
}
//判断DOM是否加载完成,如果M站已封装了类似方法,可以直接使用,例如jQuery.ready()
var readyRE = /complete|loaded|interactive/;
if(readyRE.test(document.readyState)) {
domReady();
} else {
document.addEventListener('DOMContentLoaded', function() {
domReady();
}, false);
}
function domReady() {
var cacheId = "detail"; //缓存的ID,NView模板会通过该ID读取缓存数据
var container = document.querySelector("#list"); //列表容器,根据M站实现改造
var eventType = "click"; //点击事件,根据M站实现更改,比如tap
//容器添加点击事件监听
container && container.addEventListener(eventType, function(e) {
var target = e.target;
for(; target && target !== container; target = target.parentNode) {
if(target.classList && target.classList.contains("item")) { //列表项
var data = {};
//获取图片路径
var imgElem = target.querySelector("img"); //获取当前列表项下图片对象
if(imgElem) {
data.imgPath = imgElem.getAttribute("src"); //获取图片资源路径
}
//获取标题
var titleElem = target.querySelector(".title"); //获取当前列表项下的标题对象
if(titleElem) {
data.title = titleElem.innerHTML.trim(); //获取标题
}
//将当前数据存储到缓存中
plus.storage.setItem(cacheId, JSON.stringify(data));
return;
}
}
});
}
})();
NView模板中读取缓存数据
NView模板封装了一个wap2app.getFromCache()方法,该方法有两个功能:
- 从plus.storage中读取缓存数据并自动转成object对象
- 读取缓存数据后,自动清除数据,防止下次打开同类页面时(本例为打开其它详情页),数据错乱
wap2app.getFromCache()使用方法如下:
wap2app.getFromCache(cacheId,function(data){
//data是plus.storage.getItem(cacheId)返回的数据,已自动转成object类型
})
继续上如列表示例,详情页NView模板完整代码如下:
<template>
<nviews cachemaxage="86400">
<nview id="detailNview" style="height:225px;">
<canvas>
<!--缩略图-->
<img style="top: 0;width:100%;height:225px;" src={data.imgPath}/>
<!--标题-->
<font style="bottom: 10px;height: 20px;">{data.title}</font>
</canvas>
</nview>
</nviews>
</template>
<script>
module.exports = {
data:{//默认数据,可选
imgPath:'http://www.example.com/img/default.png',
title:''
},
init: function(url) {
var self = this;//this作用域在回调函数中会变化,复制给变量self
//从缓存中读取数据
//'detail'为前页存储数据时的key
wap2app.getFromCache('detail', function(data) {
if(data) {
//读取缓存数据成功,更新数据,刷新NView
self.setData(data);
}
});
}
};
</script>
ajax获取服务端数据
NView模板也支持动态从服务端获取数据,wap2app封装了一个wap2app.getFromWebService()方法来实现AJAX请求,如下为示例代码:
<script>
module.exports = {
init: function(url) {
var self = this;//this作用域在回调函数中会变化,复制给变量self
//动态初始化数据
wap2app.getFromWebService({
url: 'your-server-url',
data: {},
type: 'post'
}, function(data) {
//TODO 如果服务端返回数据格式和模板需要的格式不同,则需要做一下转换
self.setData(data);
})
}
};
</script>