使用 Mithril.js,为什么我的 onclick 处理程序不修改 mithril 组件?
Using Mithril.js, why does my onclick handler not modify the mithril component?
我正在制作一个测验网络应用程序。我有一个名为 "answerBox" 的 class,它目前只包含一个按钮、一个 ID 和一个布尔值。我想调用一个 "check Answer" 函数来确定我的答案是否正确。
我将 onclick 分配给匿名函数,并向该函数发送一个与 answerBox 相同的对象,但 onclick 处理程序并未更改我的 answerBox 对象。它似乎正在创建本地副本。代码在这里:
//currently just boilerplate checkAnswer function. Eventually will involve server calls. It is the client-side
//controller
function checkAnswer(ansBox)
{
console.log(ansBox.IDString);
if(ansBox.IDString == "Hello")
{
console.log("BEFORE: " + ansBox.IDString);
ansBox.IDString = "Goodbye";
console.log("AFTER: " + ansBox.IDString);
return true;
}
else
{
ansBox.IDString = "Hello";
return false;
}
}
class answerBox{
constructor(IDString){
this.IDString = IDString;
this.isCorrect = false;
//to register the onclick, we need a reference to this, which we can't have unless we
//create it, since the button's "this" is not the same as the answerBox's "this", hence, "that".
var that = this;
this.checkButton = m("button",{onclick: function(){that.isCorrect = checkAnswer(that); console.log(that.isCorrect)}},"Check" + this.IDString + " " + this.isCorrect);
}
view()
{
return this.checkButton;
}
}
我使用 Mithril 将一个 answerBox 变量安装到 root,它在网页中显示得很好。单击网页上的按钮后查看控制台时,我得到:
Hello
BEFORE: Hello
AFTER: Goodbye
true
现在,发生了两件事:
- 该按钮不会更改其内容。如果 answerBox 变量真的被修改了,那么它应该有一个 "Goodbye" 的 IDString,但它没有
- 当我再次单击该按钮时,我看到了完全相同的控制台输出,表明没有任何变化。
我做错了什么?
您编写组件的方式存在一些问题:
首先,构造函数被编写为接受单个参数,IDString
- 但所有 Mithril 组件方法(包括构造函数)接收一个 vnode
对象,其中包含 attrs
和 children
,它们是在调用组件时通过超脚本传入的。因此,假设您将按如下方式调用您的组件:
m(answerBox, {IDString: 'answerBox1'})
...然后您将编写组件以在构造函数中接收 IDString
,如下所示:
class answerBox {
constructor(vnode){
this.IDString = vnode.attrs.IDString;
下一个问题是 answerBox
视图在实例化后永远不会改变,因为它的内容只在构造函数中计算一次,当定义 this.checkButton
时。与其评估视图并将其分配给 属性 只是为了调用该 属性,不如直接将其写入视图函数中。然后该组件变为:
class answerBox {
constructor(vnode){
this.IDString = vnode.attrs.IDString;
this.isCorrect = false;
}
view(){
var that = this;
return m("button", {
onclick: function(){
that.isCorrect = checkAnswer(that);
console.log(that.isCorrect)
}
},
"Check" + this.IDString + " " + this.isCorrect
);
}
}
我正在制作一个测验网络应用程序。我有一个名为 "answerBox" 的 class,它目前只包含一个按钮、一个 ID 和一个布尔值。我想调用一个 "check Answer" 函数来确定我的答案是否正确。
我将 onclick 分配给匿名函数,并向该函数发送一个与 answerBox 相同的对象,但 onclick 处理程序并未更改我的 answerBox 对象。它似乎正在创建本地副本。代码在这里:
//currently just boilerplate checkAnswer function. Eventually will involve server calls. It is the client-side
//controller
function checkAnswer(ansBox)
{
console.log(ansBox.IDString);
if(ansBox.IDString == "Hello")
{
console.log("BEFORE: " + ansBox.IDString);
ansBox.IDString = "Goodbye";
console.log("AFTER: " + ansBox.IDString);
return true;
}
else
{
ansBox.IDString = "Hello";
return false;
}
}
class answerBox{
constructor(IDString){
this.IDString = IDString;
this.isCorrect = false;
//to register the onclick, we need a reference to this, which we can't have unless we
//create it, since the button's "this" is not the same as the answerBox's "this", hence, "that".
var that = this;
this.checkButton = m("button",{onclick: function(){that.isCorrect = checkAnswer(that); console.log(that.isCorrect)}},"Check" + this.IDString + " " + this.isCorrect);
}
view()
{
return this.checkButton;
}
}
我使用 Mithril 将一个 answerBox 变量安装到 root,它在网页中显示得很好。单击网页上的按钮后查看控制台时,我得到:
Hello
BEFORE: Hello
AFTER: Goodbye
true
现在,发生了两件事:
- 该按钮不会更改其内容。如果 answerBox 变量真的被修改了,那么它应该有一个 "Goodbye" 的 IDString,但它没有
- 当我再次单击该按钮时,我看到了完全相同的控制台输出,表明没有任何变化。
我做错了什么?
您编写组件的方式存在一些问题:
首先,构造函数被编写为接受单个参数,IDString
- 但所有 Mithril 组件方法(包括构造函数)接收一个 vnode
对象,其中包含 attrs
和 children
,它们是在调用组件时通过超脚本传入的。因此,假设您将按如下方式调用您的组件:
m(answerBox, {IDString: 'answerBox1'})
...然后您将编写组件以在构造函数中接收 IDString
,如下所示:
class answerBox {
constructor(vnode){
this.IDString = vnode.attrs.IDString;
下一个问题是 answerBox
视图在实例化后永远不会改变,因为它的内容只在构造函数中计算一次,当定义 this.checkButton
时。与其评估视图并将其分配给 属性 只是为了调用该 属性,不如直接将其写入视图函数中。然后该组件变为:
class answerBox {
constructor(vnode){
this.IDString = vnode.attrs.IDString;
this.isCorrect = false;
}
view(){
var that = this;
return m("button", {
onclick: function(){
that.isCorrect = checkAnswer(that);
console.log(that.isCorrect)
}
},
"Check" + this.IDString + " " + this.isCorrect
);
}
}