秘银组件组合中的增量按钮单独点击
Increment button clicks separately in Mithril component composition
我对 Mithril.js 中组件的组成方式感到困惑。在下面的示例中,我创建了一个按钮组件,用于保存按钮点击次数的私人计数。如果我将两个这样的组件(下面的按钮 1 和 2)分别安装到两个安装点(下面的 "m1" 和 "m2"),我可以分别初始化和增加按钮点击次数 并且正确。
但是,如果我将两个按钮组件(下面的按钮 3 和 4)包装在一个较大的组件中并将此包装器组件安装到安装点 ("m3"),则按钮点击根本不会增加。这里有什么问题以及如何解决?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://unpkg.com/mithril/mithril.js"></script>
</head>
<body>
<h1>This works:</h1>
<div id="m1"></div>
<div id="m2"></div>
<h1>This doesn't work:</h1>
<div id="m3"></div>
<script>
// The factory method to generate a button component
function createButton(options) {
let {title, count} = options;
return {view: () => [
m("span", title),
m("button", {onclick: function() {count++}}, count + " clicks"),
]};
};
(function() {
// this works
m.mount(document.getElementById("m1"), createButton({title: "button 1 ", count: 0}));
m.mount(document.getElementById("m2"), createButton({title: "button 2 ", count: 10}));
// this doesn't work
m.mount(document.getElementById("m3"), {view: () => [
m("div", [m(createButton({title: "button 3 ", count: 0}))]),
m("div", [m(createButton({title: "button 4 ", count: 10}))]),
]});
})();
</script>
</body>
</html>
我发现如果按钮组件 3 和 4 是预先创建的 (而不是在包装器组件的 view() 主体内即时创建),按钮将行为正确。但是,我仍然不知道为什么按钮 1 和 2 可以动态定义,而按钮 3 和 4 不能。
<script>
(function() {
// this works
m.mount(document.getElementById("m1"), createButton({title: "button 1 ", count: 0}));
m.mount(document.getElementById("m2"), createButton({title: "button 2 ", count: 10}));
// now this also works
let b3 = createButton({title: "button 3 ", count: 0}); // created beforehand
let b4 = createButton({title: "button 4 ", count: 10}); // created beforehand
m.mount(document.getElementById("m3"), {view: () => [
m("div", [m(b3)]),
m("div", [m(b4)]),
]});
})();
</script>
第二个版本是在每次重绘时使用全新的参数创建一个全新的组件,因此 count
值在每个事件中都会被删除。
如果您改为使用秘银 closure components,它将满足您的需求。
// Button closure component
function createButton(vnode) {
let {title, count} = vnode.attrs;
return {
view: () => [
m("span", title),
m("button", {onclick: function() {count++}}, count + " clicks"),
]
};
};
(function() {
m.mount(document.getElementById("m3"), {view: () => [
m("div", [m(createButton, {title: "button 3 ", count: 0})]),
m("div", [m(createButton, {title: "button 4 ", count: 10})]),
]});
})();
我对 Mithril.js 中组件的组成方式感到困惑。在下面的示例中,我创建了一个按钮组件,用于保存按钮点击次数的私人计数。如果我将两个这样的组件(下面的按钮 1 和 2)分别安装到两个安装点(下面的 "m1" 和 "m2"),我可以分别初始化和增加按钮点击次数 并且正确。
但是,如果我将两个按钮组件(下面的按钮 3 和 4)包装在一个较大的组件中并将此包装器组件安装到安装点 ("m3"),则按钮点击根本不会增加。这里有什么问题以及如何解决?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://unpkg.com/mithril/mithril.js"></script>
</head>
<body>
<h1>This works:</h1>
<div id="m1"></div>
<div id="m2"></div>
<h1>This doesn't work:</h1>
<div id="m3"></div>
<script>
// The factory method to generate a button component
function createButton(options) {
let {title, count} = options;
return {view: () => [
m("span", title),
m("button", {onclick: function() {count++}}, count + " clicks"),
]};
};
(function() {
// this works
m.mount(document.getElementById("m1"), createButton({title: "button 1 ", count: 0}));
m.mount(document.getElementById("m2"), createButton({title: "button 2 ", count: 10}));
// this doesn't work
m.mount(document.getElementById("m3"), {view: () => [
m("div", [m(createButton({title: "button 3 ", count: 0}))]),
m("div", [m(createButton({title: "button 4 ", count: 10}))]),
]});
})();
</script>
</body>
</html>
我发现如果按钮组件 3 和 4 是预先创建的 (而不是在包装器组件的 view() 主体内即时创建),按钮将行为正确。但是,我仍然不知道为什么按钮 1 和 2 可以动态定义,而按钮 3 和 4 不能。
<script>
(function() {
// this works
m.mount(document.getElementById("m1"), createButton({title: "button 1 ", count: 0}));
m.mount(document.getElementById("m2"), createButton({title: "button 2 ", count: 10}));
// now this also works
let b3 = createButton({title: "button 3 ", count: 0}); // created beforehand
let b4 = createButton({title: "button 4 ", count: 10}); // created beforehand
m.mount(document.getElementById("m3"), {view: () => [
m("div", [m(b3)]),
m("div", [m(b4)]),
]});
})();
</script>
第二个版本是在每次重绘时使用全新的参数创建一个全新的组件,因此 count
值在每个事件中都会被删除。
如果您改为使用秘银 closure components,它将满足您的需求。
// Button closure component
function createButton(vnode) {
let {title, count} = vnode.attrs;
return {
view: () => [
m("span", title),
m("button", {onclick: function() {count++}}, count + " clicks"),
]
};
};
(function() {
m.mount(document.getElementById("m3"), {view: () => [
m("div", [m(createButton, {title: "button 3 ", count: 0})]),
m("div", [m(createButton, {title: "button 4 ", count: 10})]),
]});
})();