«это» не определено в классе - PullRequest
2 голосов
/ 15 апреля 2019

Посмотрите на следующий код.

Я создаю класс с конструктором, в котором я создаю некоторые переменные. Кроме того, я создаю некоторые асинхронные функции, из которых 3 очень похожи, а последняя способна вызывать другие.

class Project {
    data = {};
    constructor(project, api) {
        for (const key in project) {
            this.data[key] = project[key];
        }
        this.logger = new Logger(
            document.querySelector("#output"),
            `Project= ${this.data.projectId}: `
        )
        this.api = api;
    }
    async getTasks() {
        return await this.api.getTasksAsync(this.projectId);
    }
    async getRequirements() {
        return await this.api.getRequirementsAsync(this.projectId);
    }
    async getReleases() {
        return await this.api.getReleasesAsync(this.projectId);
    }
    async getToDraw(type) {
        let func = this[`get${type}`];
        console.log(func);
        let result = [];
        for (let item of await func()){
            result.push(toTaskItem(item));
        }
        return result;
    }
}

Ошибка, возникающая при выполнении функции getToDraw для инициируемого объекта класса Project (см. Выше): Error Pic

Я вызываю функцию следующим образом:

async drawDiagram(sender){
    let projectID = this.getSelectedValue("projectSelector");
    if (projectID !== "-1") {
        let project = this.projects.filter((project) => project.data.ProjectId === parseInt(projectID))[0];
        if (document.querySelector("#typeSelector").selectedOptions[0].innerText === "Full"){
            // TODO: 
        } else {
            let list = await project.getToDraw(document.querySelector("#typeSelector").selectedOptions[0].innerText);
            console.log(list);
        }
    } else {
        for (let project of this.projects) {
            // TODO:
        }
    }
}

Если никто не знает решение для меня, я уже знаю, как я мог бы сделать это по-другому, но я хотел бы сделать это так ...

Грасиас, ребята.

Ответы [ 2 ]

4 голосов
/ 15 апреля 2019

Посмотрите на эту строку

let func = this[`get${type}`];

Отсоединяет (или «отключает») функцию из ссылки this на класс, поэтому при вызове func() this становится undefined.

Есть несколько способов обойти это. Вы можете повторно связать this, используя bind, например:

let func = this[`get${type}`].bind(this);

Или вы можете явно перепривязать методы в конструкторе:

class Project {
  constructor(project, api) {
    ...
    this.getTasks = this.getTasks.bind(this);
    this.getRequirements = this.getRequirements.bind(this);
    this.getReleases = this.getReleases.bind(this);
  }
}

Или вы можете определить свои методы как свойства лямбда-выражения, например:

class Project {
  data = {};
  getTasks = () => { ... };
  getRequirements = () => { ... };
  getReleases = () => { ... };
}

Конечно, это не единственные решения, и они могут иметь некоторые побочные эффекты. Например, свойства лямбда-выражения перечисляются, поэтому они будут отображаться в Object.keys(new Project()).

4 голосов
/ 15 апреля 2019

Это потому, что когда вы сохраняете метод getRequirements в переменной func, вы отделяете его от его контекста.

Вы должны снова присоединить контекст this к func.

Первый способ: присоединить контекст только один раз

Вам просто нужно вызвать функцию func следующим образом:

func.call(this); // call func with this as context
func(); // call func with undefined context
func.call({}); // call func with empty object as context

Таким образом, вы вызываете func с помощьюthis в качестве контекста.

Второй способ: присоединить контекст для всех будущих вызовов

Перед вызовом функции необходимо bind новый контекст:

func(); // call func with undefined context
func = func.bind(this);
func(); // call func with this as context
func(); // recall func with this as context

Таким образом, вы связываете this как новый контекст для func.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...