如何在秘银中更改虚拟dom元素的内容?

时间:2019-04-25 18:05:49

标签: mithril.js virtual-dom

如何使用Mithril访问虚拟dom元素以更改其内容?我是秘银的新手,但仍在尝试解决问题。例如,我要访问ID为“ 3”的第三个div,并将其内容更改为“ Blue Jays”,而无需触摸其他任何div。
谢谢。

<div id='main'>
    <div id='one'>Yankees</div><br>
    <div id='two'>Red Sox</div><br>
    <div id='three'>Orioles</div>
</div>

2 个答案:

答案 0 :(得分:0)

在秘银中,就像在react / vue / angular中一样,您不直接对实际DOM进行操作。相反,您可以定义所需的结果,例如,要渲染发布的DOM树,您将执行以下操作:

var my_view = {
  view: vnode => m('div#main', [
    m('div#one', 'Yankees'),
    m('div#two', 'Red Sox'),
    m('div#three', 'Orioles')
  ])
}
      
m.mount(root, my_view)
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/2.0.4/mithril.js"></script>
<div id="root"></div>

数组中的m(...)函数将字符串作为第二个参数,这使输出为静态,但是我们可以将其更改为变量:

var my_view = {
  oninit: vnode => vnode.state.fave_team = 'Orioles',

  view: vnode => m('div#main', [
    m('div#one', 'Yankees'),
    m('div#two', 'Red Sox'),
    m('div#three', vnode.state.fave_team)
  ])
}
  
m.mount(root, my_view)
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/2.0.4/mithril.js"></script>

<div id="root">
</div>

在这种情况下,我使用了vnode参数的state属性,但是您也可以使用第三方状态管理器,例如flux或其他任何一种。

现在我们将其作为变量,它将在每次调用m.redraw()时显示当前值,在大多数情况下,我们不必自己进行此调用,例如:

var my_view = {
  oninit: vnode => {
    vnode.state.fave_team = 'Orioles'
  },

  view: vnode => m('div#main', [
    m('div#one', 'Yankees'),
    m('div#two', 'Red Sox'),
    m('div#three', vnode.state.fave_team),
    m('button', { onclick: () => vnode.state.fave_team = 'Dodgers' }, 'Change')
  ])
}
  
m.mount(root, my_view)
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/2.0.4/mithril.js"></script>
<div id="root"></div>

就这样,您将DOM元素中的任何动态内容都设置为对象中的变量/属性。

关于秘银的妙处之一是它不会强迫您以特定的方式进行操作,因此,如果您真的想在实际的DOM节点上工作,there are lifecycle events可以附加到任何虚拟节点上( “ vnode”)

答案 1 :(得分:0)

您可以通过oncreate()的Mithril Lifecycle事件轻松捕获HTMLElement(即HTMLInputElement)。这是来自我的代码的真实示例(使用TypeScript),在创建canvas元素并且其底层DOM在“原始” HTML级别对我可用之后,我需要连接一些事件列表器。持有dom后,我就直接操作该元素。许多人认为,为什么不使用oninit(),而是在dom生成之前使用oninit(),所以您将无法在该阶段取回元素。

现在,如果您只是这样做,则可能会发布另一个问题-“为什么浏览器视图未更新?”那是因为您必须在事件处理程序中手动执行m.redraw()。否则,秘银将不知道何时计算差异。

   const canvas = m(`.row[tabIndex=${my.tabIndex}]`, {
            oncreate: (element: VnodeDOM<any, any>) => {
                const dom = element.dom;
                dom.addEventListener("wheel", my.eventWheel, false);
                dom.addEventListener("keydown", my.eventKeyDown, false);
            }
        },