深入浅析JavaScript中数据共享和数据传递


Posted in Javascript onApril 25, 2016

数据共享和数据传递是相辅相成的,我们一起来讨论这个问题。首先要说的是共享和传递都是有作用域的。作用域就是起作用的区域,在同一个作用域数据可以共享,超过这个作用域就是跨作用域,就得用到数据传递了。

作用域

1.ui作用域

每一个ui文件缺省都有对应的ui.js。他们作为一个闭合的作用域。ui.js里根据ui文件里组件的id来获取ui对象;不同的ui文件可以定义相同id的组件。在ui.js里定义的变量只能在这个js里访问。

2.page作用域

每次调用openPage都会打开一个新的page,这个新的page会盖在旧的page之上,closePage关闭自己后就会露出被盖住的旧的page。每一个page里除了主ui文件以外,还可以包含其它很多ui文件,这些ui文件在同一个page作用域。
当page关闭的时候,所有在page里构建的对象都会释放。

3.app作用域

这个是最大的作用域,只要app没有退出,这个作用域就一直有效。

app.js属于app作用域,因为它不属于任何page。

总之,app作用域包含多个page作用域,page作用域包含多个ui作用域。

内存共享

相对文件和数据库,内存操作的速度快很多,适合于比较少的数据量操作。缺点就是app关闭后就释放了。deviceone通过以下几种方式来共享内存。

1. do_Global的memory操作(app作用域)

这个是app作用域的数据分享。这一块内存其实就是一个键值对,一个key对应一个value,所以要注意如果对一个key重新赋值,就会把以前的value覆盖。使用方法很简单。参考以下的示例,读和写分别在不同的page。

//在index.ui.js里设置值,可以设置为任何json对象,函数对象例外。
global.setMemory("key1", 1);
global.setMemory("key2", "value1");
global.setMemory("key3", [ "a", "b", "c" ]);
global.setMemory("key4", {
"k1" : "v1",
"k2" : "v2",
"k3" : "v3",
"k4" : "v4"
}); 
var label = ui("do_Label_2");
// 在memory/index.ui.js里获取值,可直接返回json对象
var global = sm("do_Global");
var content = {};
content.key1 = global.getMemory("key1");
content.key2 = global.getMemory("key2");
content.key3_2 = global.getMemory("key3")[1];
content.key4_k3 = global.getMemory("key4")["k3"];
label.text = JSON.stringify(content, null, 2);// 格式化

2. Javascript的全局变量(page作用域)

利用JavaScript自身的特性定义全局变量,通常可以定义全局变量来实现同一page下不同ui文件里的数据分享。参考以下的示例,读和写分别在不同的ui文件,但是是在一个page作用域。使用也非常简单,有二种方式:

虽然很方便,但并不推荐使用,因为使用太随意,如果是协作开发或复杂的项目,如果碰见bug,很难定位和调试。

// 在test1.ui.js里设置js的全局变量,二种方式。
// 1.不要加var前缀的变量定义,
key1 = "value1";
// 2. 把全局变量定义在deviceone对象上
deviceone.key2 = {
"k1" : "v1",
"k2" : "v2",
"k3" : "v3",
"k4" : "v4"
} 
// 在test2.ui.js里获取test1.ui.js里定义的全局变量,二种方式。
var content = {};
content.key1 = key1;
content.key2_k3 = deviceone.key2["k3"];

3. Javascript的变量(ui作用域)

这个不用太多解释,就是正常的js变量定义,只能在当前ui.js作用域有效。

var key1 = "value1";

4. sqlite的内存模式

sqlite通常是文件模式,有一种特殊的情况可以直接在内存里使用sqlite,适用于数据结构比较复杂,文本操作麻烦的方式,利用sql语句操作会灵活得多。

内存模式只能有一个,名字固定为\:memory\:.

在后面sqlite数据库介绍的地方再详细介绍。

文件共享

这个大家很好理解,文件共享是app作用域的,而且app重启后也可以访问。可以通过do_Storage组件在app的任何地方把内容写入一个文件,然后在另外一个地方读一个文件把内容读出来。参考以下的示例,读和写分别在不同的page。这里要注意的是文件读写通常是异步的,你得确保内容已经写完了,然后才能读.

// 在index.ui.js里写文件file1和file2,可以直接写json对象
var key1 = "value1";
storage.writeFile("data://file1", key1, function(data, e) {
// 回调到这里才真正把内容写完,如果在执行到这里之前去读文件有可能读不到数据
})
var key2 = {
"k1" : "v1",
"k2" : "v2",
"k3" : "v3",
"k4" : "v4"
};
storage.writeFile("data://file2", key2, function(data, e) {
// 回调到这里才真正把内容写完,如果在执行到这里之前去读文件有可能读不到数据
}) 
// 在datacache/index.ui.js里获取值,可直接返回json对象
var datacache = sm("do_DataCache");
var content = {};
content.key1 = datacache.loadData("key1");
content.key2_3 = datacache.loadData("key2")["k3"];
label.text = "datacache/index.ui.js里获取值,可直接返回json对象 \n"
+ JSON.stringify(content, null, 2);// 格式化

do_SQLite组件访问数据库数据

这个组件是一个MM组件,意味着可以创建多个实例。所有MM组件都缺省是page作用域,也可以是app作用域。创建MM组件第三个参数标示作用域。

这里要注意的是SQLite读写通常是异步的,你得确保内容已经写完了,然后才能读

1. app作用域:

// 创建一个app作用域的sqlite对象,第二个参数是这个对象的标示,第三个参数标示作用域是app
var sqlite_app = mm("do_SQLite", "sqlite_app_id1", "app")
function test_sqlite() {
// 在index.ui.js里利用这个对象创建一个数据库test.db
sqlite_app.open("data://test.db");
var stu_table = "drop table if exists stu_table"
// 同步执行一个SQL语句
sqlite_app.executeSync(stu_table);
// 创建表SQL语句
stu_table = "create table stu_table(_id integer primary key autoincrement,sname text,snumber text)";
// 同步执行一个SQL语句
sqlite_app.executeSync(stu_table);
var stu_sql = "insert into stu_table(sname,snumber) values('xiaoming','01005');"
+ "insert into stu_table(sname,snumber) values('xiaohong','01006');"
+ "insert into stu_table(sname,snumber) values('xiaoliu','01007')";
// 异步执行一个SQL语句
sqlite_app.execute(stu_sql, function(data, e) {
// 回调到这里才真正把数据插入完,如果在执行到这里之前去查询数据有可能读不到数据
deviceone.print("insert finished!")
}) 
// 根据"sqlite_app_id1"这个id获取一个app作用域的sqlite对象,第二个参数是这个对象的标示,第三个参数标示作用域是app
var sqlite_app = mm("do_SQLite", "sqlite_app_id1", "app")
// 在sqlite/index.ui.js里利用这个对象查询test.db,因为这个对象已经打开了数据库,所以不需要再open了
// 创建查询SQL语句
var stu_query = "select * from stu_table";
// 同步执行一个查询语句
var result = sqlite_app.querySync(stu_query);
label.text = "在sqlite/index.ui.js里利用这个对象查询test.db里的stu_table表的第二条数据\n"
+ JSON.stringify(result[1], null, 2);

2. page作用域:

// 创建一个page作用域的sqlite对象,唯一的id标示是memory_db_id1
var sqlite_app = mm("do_SQLite", "memory_db_id1", "page");
// 在test1.ui.js里利用这个对象创建一个内存数据库,这个名字必须写死是:memory:
sqlite_app.open(":memory:");
// 创建表SQL语句
var stu_table = "drop table if exists stu_table;"
// 内存数据库执行速度快,可以尝试都用同步
// 同步执行一个SQL语句
sqlite_app.executeSync(stu_table);
stu_table = "create table stu_table(_id integer primary key autoincrement,sname text,snumber text)";
// 同步执行一个SQL语句
sqlite_app.executeSync(stu_table);
var stu_sql = "insert into stu_table(sname,snumber) values('laoming','1');"
+ "insert into stu_table(sname,snumber) values('laohong','2');"
+ "insert into stu_table(sname,snumber) values('laoliu','3')";
// 同步执行一个SQL语句
sqlite_app.executeSync(stu_sql); 
// 在test2.ui.js里查询在test1.ui.js里创建的数据库表
// 根据memory_db_id1这个标示来获取已经创建好的sqlite对象
var sqlite_app = mm("do_SQLite", "memory_db_id1", "page");
// 创建查询SQL语句
var stu_query = "select * from stu_table";
// 同步执行一个查询语句
var result = sqlite_app.querySync(stu_query);
label.text = "在test2.ui.js里查询在test1.ui.js里创建的内存数据库表的第三条记录\n"
+ JSON.stringify(result[2], null, 2)

数据传递

数据传递涉及到跨作用域,比如不同的ui文件传递数据,不同的page传递数据。

其中最重要也是最常用的方式就是消息机制

1.消息机制

这个环节我们在文档再里详细介绍。

总之,消息机制可以在跨ui作用域传递数据,也可以跨page作用域传递数据。

2.openPage和closePage传递数据。

这个数据传递是跨page作用域,但是只限于相隔二层page之间。比如在page1的基础上打开page2,page1把一些数据传递给page2;page2关闭自身,露出page1,又可以把数据传递回page1. 数据传递可以是任何json对象。
这是一个常规而且非常好的方式,建议都这么使用。

// 在index.ui.js里openPage页面open_close_page/index.ui,传递数据
var d = {
"k1" : "v1",
"k2" : "v2",
"k3" : "v3",
"k4" : "v4"
};
app.openPage({
source : "source://view/open_close_page/index.ui",
data : d,
statusBarState : "transparent"
});
}
// 接受页面open_close_page/index.ui 关闭的时候传递回来的数据
page.on("result", function(data) {
if (data)
nf.alert(JSON.stringify(data, null, 2));
}) 
// 从index.ui.js传递过来的数据通过getData获取值,可直接返回json对象
var data = page.getData();
label.text = "从index.ui.js传递过来的数据通过getData获取值,可直接返回json对象 \n"
+ JSON.stringify(data, null, 2);// 格式化
function close_me() {
// 关闭自身,把数据传递回下一层page
app.closePage("我是从open_close_page/index.ui关闭的时候传递过来的数据");
}

关于本文给大家介绍的js数据共享和数据传递的相关知识就给大家介绍这么多,希望对大家有所帮助!

Javascript 相关文章推荐
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
Aug 28 Javascript
Mootools 1.2教程 Fx.Morph、Fx选项和Fx事件
Sep 15 Javascript
js中使用DOM复制(克隆)指定节点名数据到新的XML文件中的代码
Jul 27 Javascript
jquery实现邮箱自动补全功能示例分享
Feb 17 Javascript
jQuery验证插件 Validate详解
Nov 20 Javascript
每天一篇javascript学习小结(String对象)
Nov 18 Javascript
js 连续赋值的简单实现
Jun 13 Javascript
jQuery制作网页版选项卡
Jul 28 Javascript
jQuery增加、删除及修改select option的方法
Aug 19 Javascript
详解Vue前端对axios的封装和使用
Apr 01 Javascript
Javascript组合继承方法代码实例解析
Apr 02 Javascript
JQuery通过键盘控制键盘按下与松开触发事件
Aug 07 jQuery
Bootstrap项目实战之首页内容介绍(全)
Apr 25 #Javascript
Bootstrap每天必学之响应式导航、轮播图
Apr 25 #Javascript
Java遍历集合方法分析(实现原理、算法性能、适用场合)
Apr 25 #Javascript
下雪了 javascript实现雪花飞舞
Aug 02 #Javascript
基于node实现websocket协议
Apr 25 #Javascript
Bootstrap每天必学之导航组件
Apr 25 #Javascript
JavaScript常用字符串与数组扩展函数小结
Apr 24 #Javascript
You might like
SONY SRF-M100的电路分析
2021/03/02 无线电
PHP如何得到当前页和上一页的地址?
2006/11/27 PHP
php 上传功能实例代码
2010/04/13 PHP
PHP5.3安装Zend Guard Loader图文教程
2014/09/29 PHP
php判断一个数组是否为有序的方法
2015/03/27 PHP
PHP使用curl函数发送Post请求的注意事项
2016/11/26 PHP
JavaScript基本对象
2007/01/11 Javascript
jQuery对象与DOM对象之间的转换方法
2010/04/15 Javascript
Js动态添加复选框Checkbox的实例方法
2013/04/08 Javascript
TinyMCE汉化及本地上传图片功能实例详解
2016/05/31 Javascript
最全面的JS倒计时代码
2016/09/17 Javascript
ES6新数据结构Map功能与用法示例
2017/03/31 Javascript
Javascript中 toFixed四舍六入方法
2017/08/21 Javascript
Vue学习笔记之表单输入控件绑定
2017/09/05 Javascript
微信小程序开发之左右分栏效果的实例代码
2019/05/20 Javascript
[43:35]TI4 循环赛第二日Liquid vs Fnatic
2014/07/11 DOTA
[50:58]2018DOTA2亚洲邀请赛3月29日 小组赛A组OpTic VS Newbee
2018/03/30 DOTA
wxPython中文教程入门实例
2014/06/09 Python
Python中的zipfile模块使用详解
2015/06/25 Python
详解Python中最难理解的点-装饰器
2017/04/03 Python
python django 增删改查操作 数据库Mysql
2017/07/27 Python
Python爬虫之网页图片抓取的方法
2018/07/16 Python
python requests.post带head和body的实例
2019/01/02 Python
python tkinter canvas 显示图片的示例
2019/06/13 Python
python tkinter canvas使用实例
2019/11/04 Python
Python中url标签使用知识点总结
2020/01/16 Python
湖南卫视在线视频媒体平台:芒果TV
2019/10/30 全球购物
用C或者C++语言实现SOCKET通信
2015/02/24 面试题
教师党的群众路线教育实践活动学习心得体会
2014/10/30 职场文书
门卫岗位职责
2015/02/09 职场文书
大学生自我评价范文
2015/03/03 职场文书
2015年学校总务工作总结
2015/07/20 职场文书
python 使用Tensorflow训练BP神经网络实现鸢尾花分类
2021/05/12 Python
纯html+css实现打字效果
2021/08/02 HTML / CSS
Vue.js中v-for指令的用法介绍
2022/03/13 Vue.js
十大最强水系宝可梦,最美宝可梦排第三,榜首大家最熟悉
2022/03/18 日漫