使用 Mithril 在运行时创建新元素
Creating new elements at runtime using Mithril
使用 Javascript 框架 Mithril,我正在尝试添加 new 元素 after 已创建初始主体并渲染。
这是我的问题的最基本形式:
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
。我不知道如何解决这个问题,但我确信它与我的问题有关。
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();
}
};
更正确的方法是映射数据,在视图层创建vnode
s,而不是在视图层静态地保存一个vnodes列表你的模块范围:
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))
);
}
};
使用 Javascript 框架 Mithril,我正在尝试添加 new 元素 after 已创建初始主体并渲染。
这是我的问题的最基本形式:
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
。我不知道如何解决这个问题,但我确信它与我的问题有关。
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();
}
};
更正确的方法是映射数据,在视图层创建vnode
s,而不是在视图层静态地保存一个vnodes列表你的模块范围:
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))
);
}
};