【问题标题】:Creating new elements at runtime using Mithril使用 Mithril 在运行时创建新元素
【发布时间】:2017-11-26 02:20:10
【问题描述】:

使用 Mithril,一个 Javascript 框架,我正在尝试添加 new 元素初始主体已经创建和呈现。

这是我最基本的问题:

let divArray = [];
let newDivButton = m('button', { onclick: ()=> {
    divArray.push(m('div', "NEW DIV PUSHED"));
}}, "Add new div");

divArray.push(newDivButton);
divArray.push(m('div', "NEW DIV PUSHED"));

let mainDiv = {
    view: () => {
        return divArray;
    }
}

m.mount(document.body, mainDiv);

上面的代码将创建一个按钮和 一个 行文字说NEW DIV PUSHED。该按钮添加了一个与第一个完全相同的新文本元素。这里的问题是,即使调用了view 函数,这些附加元素也根本不会呈现。我进入了代码,清楚地看到我的 divArray 正在被填充,即使它们没有被渲染。

我注意到的一件事是,初始文本元素(被渲染的那个)的 dom 属性由实际的 div 对象填充。我数组中的所有后续文本元素都将其dom 属性设置为undefined。我不知道如何解决这个问题,但我确信这与我的问题有关。

【问题讨论】:

    标签: javascript html dom mithril.js


    【解决方案1】:

    Mithril 在 render 生命周期中内置了优化 - it won't re-render a DOM tree if the tree is identical to the last tree。由于divArray === divArray 始终为true,因此节点永远不会重新渲染。

    简单但不理想的解决方案是 slice 您的数组,因此您总是从 mainDiv#view 返回一个新数组,因此,Mithril 将始终重新渲染顶级数组:

    let mainDiv = {
      view: () => {
        return divArray.slice();
      }
    };
    

    正确的方法是映射数据,在视图层创建vnodes,而不是在模块范围内静态保留 vnode 列表:

    let data = ["Data Available Here"];
    let mainDiv = {
      view: () => {
        return [
          m(
            'button',
            { onclick: () => data.push("Data Pushed Here") },
            "Add new div"
          );
        ].concat(
          data.map(datum => m('div', datum))
        );
      }
    };
    

    【讨论】:

    • 谢谢你的回答,我明白你的解决方案。但是我确实有问题:divArray === divArray => true 在 DOM 树的范围内如何?而且没有强制秘银重新渲染的功能吗?我猜m.redraw() 也只有在 DOM 树发生变化时才会呈现?
    • m.redraw() 会做一个差异并且只重绘更改。像这样静态定义 vnode 数组意味着 mithril 看不到任何变化,并且认为它根本不需要重绘。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 2016-07-30
    • 2013-02-24
    • 1970-01-01
    • 2014-05-26
    • 2012-06-14
    相关资源
    最近更新 更多