CycleDOM

我们看下我们写好的 DOM driver:

function DOMDriver(obj$) {
  function createElement(obj) {
    // ...
  }

  obj$.subscribe(obj => {
    const container = document.querySelector('#app');
    container.innerHTML = '';
    const element = createElement(obj);
    container.appendChild(element);
  });
  const DOMSource = {
      selectEvents: function (tagName, eventType) {
          return Rx.Observable.fromEvent(document, eventType)
              .filter(evt => evt.target.tagName === tagName.toUpperCase())
      }
  };
  return DOMSource;
}

呃,暂时,它只能算是一个小玩具:

  • 它硬编码了容器对象:
const container = document.querySelector('#app');

这使得我们 HTML 中的容器变化时,需要修改代码内部。

  • 它性能不好:
container.innerHTML = '';
const element = createElement(obj);
container.appendChild(element);

每次 sink 变化,我们都会清空、然后重新渲染 container 的内容。

  • 它提供的 selectEvents 方法不够强大:
selectEvents: function (tagName, eventType) {
  return Rx.Observable.fromEvent(document, eventType)
      .filter(evt => evt.target.tagName === tagName.toUpperCase())
}

我们只能使用 HTML 标签来选择 DOM,而不能像 querySelector(selector) 那样通过元素 id 或者 class 来选择 DOM。

在实际环境中,我们可以使用 Cycle.js 官方提供的 DOM driver 来替换目前写好的、但是很弱逼的 DOM driver:

<script src="https://rawgit.com/cyclejs/cycle-core/v6.0.0/dist/cycle.js"></script>
const {h, h1, span, makeDOMDriver} = CycleDOM;

function main(sources) {
  const hover$ = sources.DOM.select('span').events('mouseover');
  return {
    DOM: hover$
      .startWith(null)
      .flatMapLatest(() =>
        Rx.Observable.timer(0, 1000)
          .map(i => h1({style: {background: 'red'}}, [span([`Seconds Elapsed ${i}`])]))
      ),
    Log: Rx.Observable.timer(0, 2000)
      .map(i => 2 * i)
  };
}


function consoleLogDriver(msg$) {
  msg$.subscribe(msg => {
    console.log(msg);
  });
}

const drivers = {
  DOM: makeDOMDriver('#app'),
  Log: consoleLogDriver
};

Cycle.run(main, drivers);

查看示例

results matching ""

    No results matching ""