2016-04-21 60 views
0

我創建了一個類別爲foo的元素。然後,我打算在點擊事件發生後將其課程與酒吧交換。然而,當我點擊元素時,連續觸發了訂閱foo的點擊事件的流。結果,元素的類沒有改變。 我怎樣才能訂閱相同元素的事件,其類別隨時間變化?CycleJs - 具有不同類別的相同元素的訂閱事件

這裏的鏈接:

https://jsbin.com/kanomonexa/edit?html,js,console,output

這裏的示例代碼:

const {div, button, makeDOMDriver} = CycleDOM; 
 
const toggleDriver = (data$)=> { 
 
    data$.subscribe(function(data) { 
 
     if (data.operation === 'remove') { 
 
      $(data.selector).removeClass(data.className); 
 
     } 
 
     else if (data.operation === 'add') { 
 
      $(data.selector).addClass(data.className); 
 
     } 
 
     else { 
 
      $(data.selector).toggle(data.className); 
 
     } 
 

 
    }); 
 

 
    return Rx.Observable.empty(); 
 
}; 
 

 
const consoleLogDriver = (data$)=>{ 
 
    data$.subscribe(data=> { 
 
     console.log(data); 
 
    }); 
 

 
    return Rx.Observable.empty(); 
 
}; 
 

 
const main = (sources) =>{ 
 
    const fooClick$ = sources.DOM 
 
    .select('.foo') 
 
    .events('click'); 
 
    const fooLog$ = fooClick$.map(_ =>'.foo is Clicked'); 
 
    const toggleFoo$ = fooClick$.flatMap(_ => { 
 
    const result = [ 
 
     { 
 
     operation: 'remove', 
 
     selector: 'button', 
 
     className: 'foo' 
 
     }, 
 
     { 
 
     operation: 'add', 
 
     selector: 'button', 
 
     className: 'bar' 
 
     } 
 
    ]; 
 
    return Rx.Observable.fromArray(result); 
 
    }); 
 
    
 
    const barClick$ = sources.DOM 
 
    .select('.bar') 
 
    .events('click'); 
 
    const barLog$ = barClick$.map(_ => '.bar is Clicked'); 
 
    const toggleBar$ = barClick$.flatMap(_ =>{ 
 
    const result = [ 
 
     { 
 
     operation: 'remove', 
 
     selector: 'button', 
 
     className: 'bar' 
 
     }, 
 
     { 
 
     operation: 'add', 
 
     selector: 'button', 
 
     className: 'foo' 
 
     } 
 
    ]; 
 
    return Rx.Observable.fromArray(result); 
 
    }); 
 
    
 
    const log$ = Rx.Observable.merge(
 
    fooLog$, 
 
    barLog$ 
 
); 
 
    const toggle$ = Rx.Observable.merge(
 
    toggleFoo$, 
 
    toggleBar$ 
 
); 
 
    
 
    const vTree$ = Rx.Observable.of(div([ 
 
    button('#button.foo',['Click me']) 
 
    
 
    ])); 
 
    
 
    return { 
 
    DOM: vTree$, 
 
    consoleLogDriver: log$, 
 
    toggleDriver:toggle$ 
 
    }; 
 
}; 
 

 
var drivers = { 
 
    DOM: makeDOMDriver('#app'), 
 
    toggleDriver: toggleDriver, 
 
    consoleLogDriver: consoleLogDriver 
 
}; 
 

 
Cycle.run(main, drivers);
<!DOCTYPE html> 
 
<html> 
 
<head> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script> 
 
<script src="https://code.jquery.com/jquery-2.1.4.js"></script> 
 
<script src="https://rawgit.com/cyclejs/cycle-core/v6.0.3/dist/cycle.js"></script> 
 
<script src="https://rawgit.com/cyclejs/cycle-dom/v9.4.0/dist/cycle-dom.js"></script> 
 

 
    <meta charset="utf-8"> 
 
    <meta name="viewport" content="width=device-width"> 
 
    <title>JS Bin</title> 
 
</head> 
 
<body> 
 
<div id="app"></div> 
 
</body> 
 
</html>

回答

1

您可能delay(0)你撥動$流安排其值到下一個事件循環,然後成功更改您的className:

... 
const toggle$ = Observable.merge(...) 
    .delay(0) 
... 

我看到你使用jQuery來切換類。根據你想要做什麼,我想它可以有一些有用的情況下(例如:在虛擬dom的範圍以外的其他地方切換一個類)。

但你的週期的應用程序是通過虛擬的DOM,所以我建議你使用正確的工具的工作,而是重建的每一個變化的vtree $處理:

... 
const currentClassName$ = Rx.Observable 
    .merge(
    fooClick$.map(_ => '.bar'), 
    barClick$.map(_ => '.foo') 
) 
    .delay(0) // fix the bug 
    .startWith('.foo'); 

const vTree$ = currentClassName$ 
    .map(currentClassName => 
    div([ 
     button(
     '#button' + currentClassName, ['Click me'] 
    ) 
    ])); 
... 

Working demo

+0

感謝正確答案。我不明白的是爲什麼我必須使用delay(0)。我的意思是有一個點擊事件,當它發生時,元素具有foo類。其中規定了酒吧的點擊事件的流程如何呢?你能解釋一下使用延遲如何解決這個問題嗎?關於使用toggleDriver,我認爲你是對的。最好使用v-dom而不是$。我創建了切換驅動程序,因爲我認爲更改元素類是一種副作用,在驅動程序中執行操作比在虛擬目錄中使用相同的代碼更容易。謝謝再次幫助 – erdal

+1

很高興爲您提供幫助。然而,我很抱歉,但我無法解釋。我只能猜測這可能是事件由dom驅動程序處理的一個問題:所有事件都會冒泡到根元素並形成一個流。然後執行.select返回按目標過濾的此流的副本。直覺上我認爲讓dom重新渲染(延遲(0))可能會有所幫助。我認爲在GitHub上報告它可能是個好問題。 (寫在我的手機上) – Fuunnx

+0

關於改變classNames,你是對的,這是一個副作用。但是,當您更改虛擬樹時,它已由domDriver處理。在時間_x_上將vTree視爲您的應用程序的圖形表示。 – Fuunnx

相關問題