首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CycleJs -订阅具有不同类的相同元素的事件

CycleJs -订阅具有不同类的相同元素的事件
EN

Stack Overflow用户
提问于 2016-04-21 05:37:00
回答 1查看 129关注 0票数 0

我用foo类创建了一个元素。然后,我打算在发生单击事件后用bar交换它的类。但是,当我单击元素时,订阅foo和bar的单击事件的流会被连续触发。因此,元素的类没有改变。如何订阅该元素类随时间变化的相同元素的事件?

下面是链接:

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

下面是示例代码:

代码语言:javascript
复制
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);
代码语言:javascript
复制
<!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>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-22 13:21:39

您可以将$ delay(0)切换到将其值调度到下一个事件循环,然后成功地更改className:

代码语言:javascript
复制
...
const toggle$ = Observable.merge(...)
  .delay(0)
...

我看到您正在使用Jquery切换您的类。根据您想要做的事情,我想它可能有一些有用的案例(例如:将页面中的某个类切换到虚拟区域之外的位置)。

但是在这里,您的循环应用程序由虚拟多姆( virtual )处理,因此我建议您使用正确的工具来完成这项工作,并在每次更改时重新构建vtree$:

代码语言:javascript
复制
...
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']
      )
    ]));
...

工作演示

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36760512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档