2017-11-23 5 views
0

私はx個の入力ボックスを持つUIを持っています。ボックスの値を左から右に1ずつ増やしたい。このplunkの機能は、https://plnkr.co/edit/82sNDb?p=previewです。Q:RXJS:入力ボックス値を「連鎖」します。

const inputValue = element => 
    Rx.Observable.fromEvent(element, 'input').map(e => 
    parseInt(e.target.value, 10)); 

const box1$ = inputValue(box1); 
const box2$ = inputValue(box2); 
const box3$ = inputValue(box3); 

box1$.subscribe((val) => { 
    box2.value = val + 1; 
    box3.value = val + 2; 
}); 

box2$.subscribe((val) => { 
    box1.value = val - 1; 
    box3.value = val + 1; 
}); 

box3$.subscribe((val) => { 
    box1.value = val - 2; 
    box2.value = val - 1; 
}); 

それ以上のボックスで拡大縮小しようとするのは難しいようですが、代わりにそれらを連鎖しようとしました。あるボックスの変更が「次の」ボックスに伝播する場所。 しかし私はそれを複雑ではない方法でやっているように思えますし、主題を使ってストリームに値をプッシュすることに頼っていました。これを行うためのよりクリーンな方法がありますか?

マイチェーンの実装:https://plnkr.co/edit/tbM5Gh?p=preview

window.addEventListener('DOMContentLoaded',() => { 
const box1 = document.querySelector('#box1'); 
const box2 = document.querySelector('#box2'); 
const box3 = document.querySelector('#box3'); 

const box1Subject = new Rx.Subject(); 
const box2Subject = new Rx.Subject(); 
const box3Subject = new Rx.Subject(); 

// link box1 -> box2 
const box1$ = createBoxStream(box1)(box1Subject)(val => val + 1) 
    .subscribe((newValue) => { 
    box2.value = newValue; 
    box2Subject.next(newValue); 
    }); 

// link box2 -> box3 
const box2$ = createBoxStream(box2)(box2Subject)(val => val + 1) 
.subscribe((newValue) => { 
    box3.value = newValue; 
    box3Subject.next(newValue); 
}); 

// link box3 -> box1 
const box3$ = createBoxStream(box3)(box3Subject)(val => val - 2) 
    .subscribe((newValue) => { 
    box1.value = newValue; 
    box1Subject.next(newValue); 
    }); 
}); 

const createBoxStream = element => subject => projection => Rx.Observable 
    .fromEvent(element, 'input') 
    .map(e => parseInt(e.target.value, 10)) 
    .merge(subject) 
    .map(projection) 
    .distinctUntilChanged(); 

答えて

0

私は少し異なるアプローチとなるだろう、我々はすべての入力からのストリームをマージし、それに応じて入力ボックスを更新することができます。このような解決策は、入力ボックスの任意の数のために動作します:私はより多くの配列インデックスフレンドリーであることを0とIDを始め

window.addEventListener('DOMContentLoaded',() => { 

    const boxesCount = 3; 
    const boxes = []; 

    let $allBoxesInput = null; 

    const keyUp = el => Rx.Observable.fromEvent(el, 'keyup'); 

    for (let i = 0; i < boxesCount; i++) { 
    const el = document.querySelector(`#box${i}`); 
    boxes.push(el); 
    $allBoxesInput = $allBoxesInput ? 
     Rx.Observable.merge($allBoxesInput, keyUp(el)) : keyUp(el); 
    } 

    $allBoxesInput.distinctUntilChanged() 
    .subscribe(event => { 
     // we get all events here 
     const id = event.target.id; 
     const index = parseInt(id.substr(id.length - 1, id.length)); 
     const value = event.target.value; 
     // update all at the right 
     for (let i = index + 1; i < boxes.length; i++) { 
     boxes[i].value = parseInt(boxes[i - 1].value) + 1; 
     } 
    }); 
}); 

<body> 
    <input type="text" id="box0"> 
    <input type="text" id="box1"> 
    <input type="text" id="box2"> 
    </body> 
+0

はい、それは私よりもはるかに良いです。ありがとう。 – Lotanot

関連する問題