官网原文:https://www.fusetools.com/learn/fusejs#reactive-operators
反应式操作符 Reactive operators
FuseJS配备了整套从其它Observable
生成新Observable
的反应式操作符,这意味着如果原始的Observable
发生了变化,则用反应式操作符生成的新的Observable
也会发生变化。
注意!只有当最后生成的
Observable
是被使用的,比如数据绑定或是需要它的值,反应式操作才会计算出结果去生成这个Observable
的值。举例说,如果你对一个Observable
集合用了map(func)操作,然后想用console.log
在终端显示出这个映射函数的结果,这些内容可能不会显示,这是因为作为结果的Observable
没有做数据绑定,遇到这种情况,你可以为了debug去手动添加一个订户。
where(condition)
将条件为真的值返回成一个新的Observable
。
新的Observable
时刻观察着旧的Observable
, 当旧的值发生变化时,新的马上随之更新。
fruits = Observable(
{ name: 'Apple' , color: 'red' },
{ name: 'Lemon' , color: 'yellow' },
{ name: 'Pear' , color: 'green' },
{ name: 'Banana', color: 'yellow' });
goodFruits = fruits.where(function(e){
return e.color === 'yellow';
});
如果根据条件产生了一个Observable
,where
操作符也会观察这这个条件。
map(func)
对一个Observable
里的每个值都调用一遍参数函数,结果返回成一个新的Observable
。
var numbers = Observable(1, 4, 9);
var roots = numbers.map(function(number) {
return Math.sqrt(number);
});
上例中,变量roots
里值由numbers
的数字求平方根组成,numbers
里的值保持不变。
count()
从一个Observable
得出其包含值的总数,然后存为另一个计数用的Observable
。当原来的Observable
新增或删除项时,计数的Observable
数字也随之改变。
books = Observable("UX and you",
"Observing the observer",
"Documenting the documenter");
numBooks = books.count(); //result: 3
count(condition)
和上一条比,多了一个过滤条件,意思是只有条件为true
的才计数。
not()
取反,将一个Observable
的相反值返回成新的Observable
, 比如一个Observable
的值为true
,则返回false
, 反之亦然。
falseValue = Observable(false);
trueValue = falseValue.not();
filter(condition)
只有通过给定条件的才会返回为另一个变种的Observable
,不然保持原有Observable
的值。
这方法只用考虑Observalbe
的首值或单独值。
expand(func)
将一个只包含一个数组的Observable
拆散,把数组里的所有值作为单独项组合成另一个Observable
。
Observable([1,2,3]).expand() -> Observable(1,2,3)
订阅更新 Subscribing to updates
addSubscriber(func)
手动使一个Observable
对变化做反应,只需要使用addSubscriber
方法。这样当发生变化时,func
就会运行。
removeSubscriber(func)
当对一个Observable
值操作完成后,注意别忘了删除订阅(subscription),否则内存垃圾会越来越多。
username.removeSubscriber(usernameLogger);
其它
depend()
failed(message)
setValueExclusive(value, excludingObserver)
给一个Observable
赋值而不通知excludingObserver
。
var observable = Observable(1);
var shouldGetNotification = function() { }
var shouldNotGetNotification = function() { }
observable.addSubscriber(shouldGetNotification);
observable.addSubscriber(shouldNotGetNotification);
observable.setValueExclusive(2, shouldNotGetNotification);
toString()
返回一个形容该Observable
的字符串,包括其内容。
var testObservable = Observable(1, "two", "3");
testObservable.toString(); // "(observable) 1,two,3"
话题
Observable
可以用来做很多事情:
- 数据绑定Data Binding
- 异步编程Asynchronous programming
- 反应式编程Reactive programming
APIs 应用程序编程接口
Polyfills 兼容代码
FuseJS在所有支持平台上的运行环境为EcmaScript5.1。这里没有浏览器什么事儿,FuseJS只是提供了一个浏览器标准库的子集。为了让第三方库能工作,FuseJS用一些Polyfills
兼容代码提供特色功能,典型的就是浏览器的功能。这些代码目前并不完备,所以有问题请到论坛发帖。
fetch
这是主要做HTTP request的方式。
下面是一个fetch
的示例,首先用一个JavaScript对象转成JSON数据,POST
到服务器端,然后服务器端返回JSON数据,再转成另一个JavaScript对象。
var status = 0;
var response_ok = false;
fetch('http://example.com', {
method: 'POST',
headers: { "Content-type": "application/json"},
body: JSON.stringify(requestObject)
}).then(function(response) {
status = response.status; // Get the HTTP status code
response_ok = response.ok; // Is response.status in the 200-range?
return response.json(); // This returns a promise
}).then(function(responseObject) {
// Do something with the result
}).catch(function(err) {
// An error occured parsing Json
});
- 完整的
fetch
的文档见于MDN。
XMLHttpRequest
FuseJS支持XMLHttpRequest
, 具体见MDN。
Promise
对于Promise
,FuseJS也有支持,具体见MDN。
setTimeout
延时两秒再运行一个函数:
setTimeout(function() { alert("Alert"); }, 2000);
用setTimeout
做一个循环:
function poller() {
// Do work (...)
// And again in 1 second
setTimeout(poller, 1000);
}
- 关于
setTimeout
参见MDN
Storage
Storage
API可以用来将文本保存为应用目录下的文件。
var storage = require('FuseJS/Storage');
write 写入
将字符串写入指定的文件。
storage.write(filename, value)
-
filename
- 文件名 -
value
- 需要写进文件的内容
返回的是一个含有布尔值的Promise
, 可以告知内容写入文件成功与否。
storage.write("filename.txt", "filecontent");
read 读取
storage.read(filename)
-
filename
- 要读取的文件
返回的是一个包含文件内容字符串的Promise
。
storage.read("filename.txt").then(function(content) {
console.log(content);
}, function(error) {
console.log(error);
});
保存文件的实际目录在不同的平台上也不尽相同。
writeSync 同步写
同步写入数据到应用文件夹, 如成功写入则返回true
:
var wasWritten = storage.writeSync("filename.txt", "filecontent");
警告:此调用易堵塞,如果写入大量数据,请使用
Storage.write
。
readSync 同步读
在应用的文件夹里同步读取文件内的数据:
var data = storage.readSync("filename.txt");
警告: 此调用易堵塞,如果读取大量数据,请使用
Storage.read
。
deleteSync 同步删
从应用的文件夹里删除一个文件,成功后返回true
:
var data = storage.readSync("filename.txt");
Lifecycle 生命周期
用JavaScript响应Lifecycle
的事件:
var lifecycle = require('FuseJS/Lifecycle');
lifecycle.onEnteringForeground = function() {
initialize();
};
下列生命周期事件将被提升:
App的开始事件是隐式的,这就是当你的JS代码头一次被评估时。
-
onEnteringForeground
- App脱离挂起状态,开始运行。App开始时可以得到该事件。 -
onEnteringBackground
- App脱离运行状态,将被挂起。 -
onEnteringInteractive
- App进入高度交互状态,开始接受事件。 -
onExitedInteractive
- App部分被遮盖或不再是焦点状态(比如你拖出系统通知栏的时候)。 -
onTerminating
- App将被关闭
Phone 电话
Phone
API用来初始化一个呼叫请求:
var phone = require('FuseJS/Phone');
phone.call("number");
Camera 摄像头
可以让你使用设备的摄像头拍照。
var camera = require('FuseJS/Camera');
示例:
camera.takePicture({ targetWidth: 640, targetHeight: 360}).then(function(file)
{
// file is a standard JavaScript File object
// file.path contains the path to the saved image on the device
}).catch(function(e) {
console.log(e);
});
如果不想根据EXIF数据自动地旋转照片,你可以给原始请求加上一个correctOrientation
值。
takePicture function
用设备的摄像头拍照;。
camera.takePicture({ targetWidth: width, targetHeight: height, correctOrientation: shouldCorrect })
选项对象包括下列属性:
-
targetWidth
- 想要拍的照片宽度,单位为像素,如果省略,缺省值为上次的。 -
targetHeight
- 想要拍的照片高度,单位为像素,如果省略,缺省值为上次的。 -
correctOrientation
- 如果想要纠正照片的朝向,就设为true
。
该方法在拍照成功后返回一个Promise
,最后生成一个file
对象指向存储盘上的JPG图片。
提示:targetWidth
和targetHeight
只是建议值,最终拍摄的照片可能是任何尺寸。(WTF!)
Vibration
使用设备的震动功能。
var vibration = require('FuseJS/Vibration');
用例:
vibration.vibrate(0.8);
震动0.8秒。
InterApp
InterApp
模块是专门为简化App之间通讯而设计的。
var interApp = require('FuseJS/InterApp');
目前它就处理两件事:
- 用一个Uri请求启动另一个App
- 接受另一个App的Uri启动请求
URI = Universal Resource Identifier 统一资源标识符
launchUri(uri)
用字符串参数调用该方法,Fuse就会请求系统打开目标App并处理Uri。
interApp.launchUri ('purple://some/uri')
onReceivedUri(uri)
这是一个回调函数,用来告知其它App正用一个Uri启动你的App。所以要接受这个通知,首先得给你的App定义一个Uri scheme
, How?Fuse里很简单,只要在unoproj
文件的Mobile
字段加上一个UriScheme
元素即可,如下所示:
"Mobile": {
"UriScheme": "YourScheme",
...
},
就这样,每当设备上一个有着YourScheme
字段的Uri
被打开时,你的App就会被打开,并用完整的Uri
调用onReceivedUri
回调函数。
当上面的调用发生时,如果你的App已经打开了onReceivedUri
,这时App会暂时脱离交互模式,别担心,这是完全正常的。
在你的JavaScript代码里使用该回调函数,如下所示:
var interApp = require('FuseJS/InterApp');
interApp.onReceivedUri = function(uri) {
console.log ("js recieved Uri: " + uri);
};
网友评论