資料共享和資料傳遞是相輔相成的,我們一起來討論這個問題。首先要說的是共享和傳遞都是有作用域的。作用域就是起作用的區域,在同一個作用域資料可以共享,超過這個作用域就是跨作用域,就得用到資料傳遞了。
作用域
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表的第二条数据 " + 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数据共享和数据传递的相关知识就给大家介绍这么多,希望对大家有所帮助!