【问题标题】:How to change contents of a virtual dom element in Mithril?如何更改 Mithril 中虚拟 dom 元素的内容?
【发布时间】:2019-09-15 05:43:18
【问题描述】:

如何使用 Mithril 访问虚拟 dom 元素以更改其内容?我是 Mithril 的新手,仍在努力解决问题。例如,我想访问 ID 为“three”的第三个 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>

【问题讨论】:

  • 您可以使用 vnode 的 dom 属性访问 dom。您只需将此 dom 分配给 vnode 对象。比如 vnode.state.el = {
    ....
    }

标签: mithril.js virtual-dom


【解决方案1】:

在 mithril 中,就像在 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 ")

【讨论】:

    【解决方案2】:

    您可以使用 oncreate() 的 Mithril Lifecycle 事件轻松捕获 HTMLElement(即 HTMLInputElement)。这是我的代码(在 TypeScript 中)中的一个实际示例,我需要在创建画布元素后连接一些事件侦听器,并且它的底层 DOM 在“原始”HTML 级别可供我使用。一旦你掌握了dom,我就会直接操纵那个元素。很多人认为为什么不使用oninit(),但是oninit()是在dom生成之前,所以你不会在那个阶段取回元素。

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

       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);
                }
            },
    

    【讨论】:

      猜你喜欢
      • 2016-02-09
      • 2011-10-25
      • 1970-01-01
      • 2019-07-26
      • 2020-02-05
      • 2017-05-06
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多