При использовании Mithril. js, почему мой обработчик onclick не изменяет мифриловый компонент? - PullRequest
0 голосов
/ 11 февраля 2020

Я делаю веб-приложение для викторины. У меня есть класс под названием «answerBox», который в настоящее время содержит только кнопку, идентификатор и логическое значение. Я хочу вызвать функцию «Проверить ответ», которая определяет, является ли мой ответ правильным или нет.

Я назначаю 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;
    }
}

У меня есть переменная answerBox, смонтированная на root с использованием Mithril, и она прекрасно отображается на веб-странице. Когда я смотрю на консоль после нажатия кнопки на веб-странице, я получаю:

Hello
BEFORE: Hello
AFTER: Goodbye
true

Теперь происходят две вещи:

  1. Кнопка не меняет то, что говорит. Если переменная answerBox действительно была изменена, то она должна иметь IDString «Goodbye», но она не
  2. Когда я снова нажимаю кнопку, я вижу точно такой же вывод консоли, что означает, что ничего меняется.

Что я делаю не так?

1 Ответ

2 голосов
/ 12 февраля 2020

Есть несколько проблем с тем, как вы написали свой компонент:

Прежде всего, конструктор написан так, чтобы принимать один аргумент, 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
    );
  }
}

Приведенный выше код должен давать ожидаемые результаты!

...