[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 ...
随机推荐
- mysql 在windows下的安装,开发基础与要点
1:安装(windows下) 官网下载.msi文件 运行安装时只需要安装server就行了 在环境变量中配置到bin目录:e.g:C:\programFile\...mysql\bin 完成后进入wi ...
- pd的django To do list教程-----(2)models模型的建立
1:在models.py中建表 from django.db import models class Tcontent(models.Model): content = models.CharFiel ...
- MVC---404页面配置
参考地址1:http://benfoster.io/blog/aspnet-mvc-custom-error-pages 参考地址2:https://msdn.microsoft.com/en-us/ ...
- ref参数的用途
ref参数 能够将一个变量带入方法进行改变,改变完成后再将改变完成后的变量带出方法 ref参数要求在方法外必须为值赋值,而方法内可以不赋值 static void Main(string[] arr) ...
- angularjs中ng-switch的用法
<!DOCTYPE html> <html lang="zh-CN" ng-app="app" ng-controller="ctr ...
- 使用PowerDesigner 15对现有数据库进行反向工程(图解教程)
1.启动PD 2.菜单:File->Reverse Engineer ->Database 出来New Physical Data Model对话框 点击“确定”按钮,弹出Database ...
- html meta标签属性用法集合
1.<meta name="generator" contect="">用以说明生成工具(如Microsoft FrontPage 4.0)等: 2 ...
- python 中变量的命名规范
出自:http://www.diybl.com/course/3_program/python/20111130/563643.html 模块名: 小写字母,单词之间用_分割 ad_stats.py ...
- 汉诺塔问题C++实现
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang 以下进行汉诺塔问题的递归实现 #include <iostream.h> int gb ...
- 剑指offer中二进制中1的个数
容易想到的是将n一位一位的和1进行比较,产生如下代码 但是这样的话会出下面的问题 那么就是原数据不动,将1依次移动进行比较有如下的代码 一种更简单的方法是: 这样做的思路是 总而言之