更灵活的 DOM driver

目前,DOM driver 接收的 sink 是一个发出字符串的 Observable:

function DOMDriver(text$) {
  text$.subscribe(text => {
    $app = document.querySelector('#app');
    $app.textContent = text;
  });
  const DOMSource = Rx.Observable.fromEvent(document, 'click');
  return DOMSource;
}

为了让它更加灵活,它接收的应当是一个能发出 DOM Element 对象的 Observable,假定 main() 发出的 Observable 为:

function main(sources) {
  const click$ = sources.DOM;
  return {
    DOM: click$
      .startWith(null)
      .flatMapLatest(() =>
        Rx.Observable.timer(0, 1000)
          .map(i => ({
            tagName: 'H1',
            children: [{
              tagName: 'SPAN',
              children: [
                `Seconds elapsed ${i}`
              ]
            }]
          }))
      ),
    Log: Rx.Observable.timer(0, 2000)
      .map(i => 2 * i)
  };
}

我们让 DOM driver 能够递归的创建 DOM Element:

function DOMDriver(obj$) {
  function createElement(obj) {
    const element = document.createElement(obj.tagName);
    obj.children
      .filter(c => typeof c === 'object')
      .map(createElement)
      .forEach(e => element.appendChild(e));
    obj.children
      .filter(c => typeof c === 'string')
      .forEach(str => element.innerHTML=str);
    return element;
  }

  obj$.subscribe(obj => {
    const container = document.querySelector('#app');
    container.innerHTML = '';
    const element = createElement(obj);
    container.appendChild(element);
  });
  const DOMSource = Rx.Observable.fromEvent(document, 'click');
  return DOMSource;
}

查看示例

results matching ""

    No results matching ""