[Cycle.js] Read effects from the DOM: click events
So far we only had effects that write something to the external world, we are not yet reading anything from the external world into our app. This lesson shows how we can change the DOM Driver to return a "DOM Source" representing read effects, such as click events. We will leverage that to create an interactive application.
// Logic (functional)
function main() {
return {
DOM: Rx.Observable.timer(0, 1000)
.map(i => `Seconds elapsed ${i}`),
Log: Rx.Observable.timer(0, 2000).map(i => 2*i),
};
} // Effects (imperative)
function DOMEffect(text$) {
text$.subscribe(text => {
const container = document.querySelector('#app');
container.textContent = text;
});
} function consoleLogEffect(msg$) {
msg$.subscribe(msg => console.log(msg));
} const effects = {
DOM: DOMEffect,
Log: consoleLogEffect
} function run(mainFn, effects){
const sinks = mainFn();
Object.keys(effects)
.forEach( (effectKey)=>{
effects[effectKey](sinks[effectKey]);
})
} run(main, effects);
Source: stands for input, read effect
sink: stands for output, write effect
So main() function need to take a param 'DOMSource' and effects function need return value:
function main(DOMSource) {
...
}
function DOMDriver() {
...
const DOMSource = Rx.Observable.fromEvent(document, 'clicik');
return DOMSource;
}
function run(mainFn, drivers) {
const sinks = mainFn(DOMSource);
const DOMSource = drivers['DOM'](sinks['DOM'])
....
}
The problem in the code above is that:
the main function need param 'DOMSource' which is returned by the driver DOMDriver. But for create DOMSource in run() function, we need pass DOMSource to the main() function. So 'DOMSource' is actually used before it created.
I can simply the problem as:
a = f(b); // we need b to create a
b = g(a) // we need a to create b
So there is a cycle going on between main() function and driver() function.
The solution to sovle this problem is :
A is an observable and also B is an observable. If we actually instead of using B, we could use something like B proxy here. Because B proxy is now available for f() as an argument.
Then that helps us to make A, and then given A we can make B. Then now that we have B, we can feed back all of the events that happen on B into B proxy. So that's what we're going to try to achieve.
bProxy = ...
a = f(bProxy)
b = g(a)
bProxy.imitat(b)
So the code looks like:
// Logic (functional)
function main(DOMSource) {
const click$ = DOMSource;
return {
DOM: click$
.startWith(null)
.flatMapLatest(() =>
Rx.Observable.timer(0, 1000)
.map(i => `Seconds elapsed ${i}`)
),
Log: Rx.Observable.timer(0, 2000).map(i => 2*i),
};
} // source: input (read) effects
// sink: output (write) effects // Effects (imperative)
function DOMDriver(text$) {
text$.subscribe(text => {
const container = document.querySelector('#app');
container.textContent = text;
});
const DOMSource = Rx.Observable.fromEvent(document, 'click');
return DOMSource;
} function consoleLogDriver(msg$) {
msg$.subscribe(msg => console.log(msg));
} // bProxy = ...
// a = f(bProxy)
// b = g(a)
// bProxy.imitate(b) function run(mainFn, drivers) {
const proxyDOMSource = new Rx.Subject();
const sinks = mainFn(proxyDOMSource);
const DOMSource = drivers.DOM(sinks.DOM);
DOMSource.subscribe(click => proxyDOMSource.onNext(click));
// Object.keys(drivers).forEach(key => {
// drivers[key](sinks[key]);
// });
} const drivers = {
DOM: DOMDriver,
Log: consoleLogDriver,
} run(main, drivers);
[Cycle.js] Read effects from the DOM: click events的更多相关文章
- [Cycle.js] Fine-grained control over the DOM Source
Currently in our main() function, we get click$ event. function main(sources) { const click$ = sour ...
- [Cycle.js] Customizing effects from the main function
How can we show one string on the DOM, and a completely different string on Console log? This lesson ...
- [Cycle.js] The Cycle.js principle: separating logic from effects
The guiding principle in Cycle.js is we want to separate logic from effects. This first part here wa ...
- [Cycle.js] Making our toy DOM Driver more flexible
Our previous toy DOM Driver is still primitive. We are only able to sends strings as the textContent ...
- [Cycle.js] From toy DOM Driver to real DOM Driver
This lessons shows how we are able to easily swap our toy DOM Driver with the actual Cycle.js DOM Dr ...
- 学习RxJS:Cycle.js
原文地址:http://www.moye.me/2016/06/16/learning_rxjs_part_two_cycle-js/ 是什么 Cycle.js 是一个极简的JavaScript框架( ...
- jquery.cycle.js简单用法实例
样式: a{text-decoration: none;} *{;;} /*容器设置*/ .player { width:216px; height:248px; background:url(htt ...
- [Cycle.js] Generalizing run() function for more types of sources
Our application was able to produce write effects, through sinks, and was able to receive read effec ...
- [Cycle.js] Hello World in Cycle.js
Now you should have a good idea what Cycle.run does, and what the DOM Driver is. In this lesson, we ...
随机推荐
- Linux字符设备中的两个重要结构体(file、inode)
对于Linux系统中,一般字符设备和驱动之间的函数调用关系如下图所示 上图描述了用户空间应用程序通过系统调用来调用程序的过程.一般而言在驱动程序的设计中,会关系 struct file 和 struc ...
- border和outline区别
border和outline区别: border支持box-sizing: border-box,当有边距时,是新增了边框后在按照以前的边距处理 outline不支持box-sizing: borde ...
- php设计模式——单例模式
单例模式概念 单例模式是指整个应用中类只有一个对象实例的设计模式. 单例模式的特点 一个类在整个应用中只有一个实例 类必须自行创建这个实例 必须自行向整个系统提供这个实例 php中使用单例模式的原因 ...
- HTML5 Canvas前台压缩图片并上传到服务器
1.前台代码: <input id="fileOne" type="file" /> <input id="btnOne" ...
- C#中的switch case
在C#中switch(type){case tpye1:break;case tpye2:break;case tpye3:break;case tpye4:break;};其中type可以是数字,也 ...
- 记一次lnmp环境下无法执行php文件
lnmp环境搭建好后却无法正常执行php文件,坑爹啊!~ [错误状况] 页面直接打印出php代码内容: php文件无法执行?: 查看nginx配置文件: server { listen 80; ser ...
- Redhat修改本地yum源
1.将Centos系统的ios文件传到服务器,比如传到/root目录下: 2.将ios文件挂载到本地,需要在本地建立一个文件夹,比如/yum; mkdir /yum mount -o loop /ro ...
- c笔试题(1)
1.sizeof和strlen的区别 #include<stdio.h> #include<string.h> int main() { char a[10] = " ...
- KM算法专题
原文:http://972169909-qq-com.iteye.com/blog/1184514 题目地址:这里. 1)求图中所有环的总长度(环的长度不唯一)的最小值.当无法得到完备匹配时说明环不存 ...
- CSS的margin塌陷
一.两个div并列,上面div的margin-bottom和下面div的margin-top会塌陷,也就说会取上面div的margin-bottom和下面div的margin-top的最大值作为两个并 ...