mithril.js - 为什么秘银子组件状态改变不触发更新?
问题描述
以下代码按预期工作:它创建了两个计数器按钮,它们保持其状态并在单击时更新:
let Counter = function (vnode) {
let count = 0
return {
view: (vnode) => {
return m("button",
{
onclick: function () {
console.log(count++)
}
}, "Count: " + count)
}
}
}
let Counters = {
view: () => [
m(Counter),
m(Counter),
]
}
m.mount(document.body, Counters)
但是,如果我Counter
在单独的变量中定义组件数组并将其传递给Counters
视图函数,则视图将停止更新。状态仍然存在,我可以看到控制台记录了递增计数,但屏幕上没有任何变化。这是更新的代码:
let Counter = function (vnode) {
let count = 0
return {
view: (vnode) => {
return m("button",
{
onclick: function () {
console.log(count++)
}
}, "Count: " + count)
}
}
}
let counters =
[
m(Counter),
m(Counter),
]
let Counters = {
view: () => counters
}
m.mount(document.body, Counters)
为什么会发生这种情况?这是我正在处理的一个更复杂的 Mithril 应用程序的玩具示例,我想对子组件数组进行任意排序。
解决方案
我认为可能发生的情况是,当您设置数组时,组件正在“渲染”,因为 JavaScript 如何评估表达式,counters
数组中的 Mithril 组件在您稍后尝试挂载它们之前已经执行,所以 Mithril重绘机制(通过m.mount
或m.route
)可能不“知道”这些组件,因此不属于重绘队列。
let counters =
[
m(Counter),
m(Counter),
]
我不确定您要实现什么,但也许更好的解决方案是将数据数组保存在纯 JS 数据结构中,当您需要实际渲染组件时,您可以映射数据结构,例如
let Counter = function (vnode) {
return {
view: (vnode) => {
return m("button",
{
onclick: function () {
console.log(this, vnode.attrs.count++);
}
}, "Counter #" + vnode.attrs.id +": " + vnode.attrs.count)
}
}
}
let counterList = [
{ id: 1, name: "Something 1", count: 0 },
{ id: 2, name: "Something 2", count: 0 },
{ id: 3, name: "Something 3", count: 0 },
]
let reorderCountersByCountAscending = () => {
counterList.sort((a, b) => (a.count > b.count) ? 1 : -1)
}
let Counters = {
view: () => {
return m('div',
m('button', { onclick: reorderCountersByCountAscending }, 'Reorder Children'),
counterList
.map((counterListItem) => m(Counter, counterListItem))
)
}
}
m.mount(document.body, Counters);
这不是一个理想的实现,有很多状态突变以非常隐含的方式发生,它可能会在现实世界的应用程序中导致很多混乱,但我希望它描述了这种方法。
这里还有几个例子可以看: https ://jsfiddle.net/9hu2yd1s/
推荐阅读
- powershell - PowerShell 变量类型以保存大量数字
- r - 确定最近的站点并从该位置选择另一个变量
- asp.net-web-api - Swagger-Net 支持 API Key 认证
- javascript - Javascript按部分字符串排序数组
- laravel - 如何使用带有 laravel 和 vue js 的推送器来创建实时聊天?
- angularjs - 根据条件显示 angularjs 应用程序弹出窗口的最佳选项
- javascript - console.log 函数在快速路由(node.js)中不起作用
- r - 如何从 github 安装一个包?
- javascript - 使用nodejs从firestore文档中删除字段
- angular - 为什么 Angular 5 组件通过明确的焦点刷新得更快?