2

在cycle.js中加载 DOM 后如何执行 javascript ?我不能把它放在我main()的,因为那时 DOM 没有加载。对于上下文,我基本上是在尝试初始化一个需要目标 DOM 元素存在的精美自动完成功能,如果我的方法有误,请随时指点。

我试过这个:

sources.DOM.select(':root')
  .observable.take(1)
  .subscribe((element) => initAutoCompl())

...但select在返回null时,我也尝试选择其他元素。

4

2 回答 2

2

在 DOM 准备好后执行 JS 代码的一种方法(使用CycleJSxstream )是运行(否则)不可操作的 observable。为此,请select ':root'分配一个不存在的事件,并使用startWith. 启动流后,运行一个map执行您的设置功能的程序。要订阅 observable,请将其发送给非操作驱动程序:

function main (sources) {

  // Initiate observable, run setup function
  const noop$ = sources.DOM.select(':root').events('noop')
    .startWith(1).map(noop => runSetup())

...

  return {
    DOM: vdom$,
    noop: noop$
  }
}

...

Cycle.run(main, {
  DOM: makeDOMDriver('#app'),

  // non-operative driver
  noop: noop$ => { noop$.addListener(
    {next: noop => {}, error: ()=>{}, complete: ()=>{}}
  ) }
})

Codepen.io 运行设置示例


of另一种方法是在驱动程序中运行您的设置脚本并使用可观察的触发它。

function main (sources) {

  // trigger observable
  const setup$ = xs.of(1)

...

  return {
    DOM: vdom$,
    setup: setup$
  }
}

Cycle.run(main, {
  DOM: makeDOMDriver('#app'),

  // setup driver
  setup: setup$ => { setup$.addListener({next: setup => {
    // setup code goes here
    console.log('run setup: ', document.querySelector('#app').children.length)
  }, error: ()=>{}, complete: ()=>{}}) }
})

Codepen.io 设置驱动程序示例。


如果在创建 DOM 元素之前需要用户输入:

function main (sources) {

  const click$ = sources.DOM.select('div#clickme').events('click')
  const vdom$ = click$
    .mapTo(div('#newDomElement',"I'm new."))
    .startWith(div('#clickme','Click me.'))

  return {
    DOM: vdom$,
    setup: click$
  }
}

Cycle.run(main, {
  DOM: makeDOMDriver('#app'),
  setup: setup$ => { setup$.addListener({next: setup => {
    // setup code goes here
    initAutoComplDummy()
  }, error: ()=>{}, complete: ()=>{}}) }
})

Codepen.io 用户输入后设置驱动程序示例

于 2018-03-28T16:47:49.040 回答
1

我实际上问错了我的问题,因为当我实施我的解决方案时,我意识到自动完成不在第一页上,所以bloodyKnuckles 解决方案虽然正确回答了问题,但并没有解决我的问题。

所以这里是如何在 cycle.js 中的 DOM 上呈现任意项目后运行 javascript

在你的主要里面

 const elementId$ = sources.DOM.elements().filter(c => (document.getElementById('myRenderedElementId') !== null)).filter(c => c).take(1).map(c => {
       // run custom javascript
    });

    elementId$.addListener({
        next: function (value) {
        },
        error: function (err) {
            alert('err: ' + name + ' ' + err);
        },
        complete: function () {
        }
    });
于 2018-03-28T21:04:59.337 回答