如何为不同的可观察函数创建全局变量?
例如迭代编号,或从数组中删除一个可观察对象,添加另一个对象等的数组。
// RxJS v6+
import { fromEvent, combineLatest } from 'rxjs';
import { mapTo, startWith, scan, tap, map } from 'rxjs/operators';
const setHtml = id => val => (document.getElementById(id).innerHTML = val);
const addOneClick$ = (id, iter) =>
fromEvent(document.getElementById(id), 'click').pipe(
mapTo(10),
startWith(0),
scan((acc, curr) => {iter++; return acc + curr}),
tap(setHtml(`${id}Total`)),
// it changed only in this object
tap(val => console.log(`${iter}`))
);
const predefVar = 100;
const combineTotal$ = combineLatest(addOneClick$('red', predefVar), addOneClick$('black', predefVar))
//I need see chancged predefVar varible here
.pipe(map(([val1, val2]) => `${val1 + val2} clicked: ${predefVar}`))
.subscribe(setHtml('total'));
HTML视图
<div>
<button id='red'>Red</button>
<button id='black'>Black</button>
</div>
<div>Red: <span id="redTotal"></span> </div>
<div>Black: <span id="blackTotal"></span> </div>
<div>Total: <span id="total"></span> </div>
答案 0 :(得分:0)
如果要避免使用全局变量,则需要从addOneClick $传递它。
const addOneClick$ = (id, iter) =>
fromEvent(document.getElementById(id), 'click').pipe(
mapTo(10),
startWith(0),
scan((acc, curr) => {iter++; return acc + curr}),
map(res=>[res,iter])
....
)
答案 1 :(得分:0)
当您在函数中传递原始参数时,该值被复制为其他变量。无论您分配什么,全局变量都不会更改。如果您定义object
,则可以解决此问题,因为它作为ref传递,因此可以更改其属性。
如果您将predefVar
定义为全局变量,只需直接调用它即可:
var predefVar = 100;
const addOneClick$ = (id) =>
fromEvent(document.getElementById(id), 'click').pipe(
mapTo(10),
startWith(0),
scan((acc, curr) => {predefVar++; return acc + curr}),
tap(setHtml(`${id}Total`)),
// it changed only in this object
tap(val => console.log(`${iter}`))
);
但是,根据使用情况,应尽可能避免使用全局变量。在这种情况下,您可以像这样使用纯Rx.js:(playground)
const {
of,
merge,
combineLatest,
fromEvent
} = rxjs;
const {
scan,
mapTo,
startWith,
tap,
map,
} = rxjs.operators;
const setHtml = id => val =>
(document.getElementById(id).innerHTML = val);
const addOneClick$ = (id) =>
fromEvent(document.getElementById(id), 'click').pipe(
mapTo(10),
startWith(0),
scan((acc, curr) => acc + curr),
tap(setHtml(`${id}Total`)),
);
const totalClick$ = (arr$, defaultValue) =>
merge(...arr$).pipe(
startWith(defaultValue - arr$.length),
scan((acc) => acc + 1, defaultValue),
);
const red$ = addOneClick$('red');
const black$ = addOneClick$('black');
const total$ = totalClick$([red$, black$], 100);
const combineTotal$ = combineLatest(
total$, red$, black$,
)
.pipe(
map(([total, val1, val2]) => `${val1 + val2} clicked: ${total}`)
)
.subscribe(
setHtml('total')
);