Почему атрибуты в классе не определены, если они были инициализированы ранее? - PullRequest
0 голосов
/ 22 сентября 2019

В моем коде у меня есть класс под названием WorkspaceDatabase, который получен из динамического дерева Пример .Я уже добавил некоторую отладочную информацию, чтобы лучше понять проблему.

Проблема:

В complete() происходит первая странная вещь: this.wsnodes.push не удаетсяс TypeError: Cannot read property 'push' of undefined, но, насколько я вижу, я его инициализировал.

Следующее, что происходит, это то, что в getChildren console.log(this.workspaces); возвращает массив длины 0. Но initialData () запускается раньшеэто и this.workspaces получает значение ws, и оно правильно выводится на консоль (7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}].

Может кто-нибудь объяснить, что я не правильно понимаю?

export class WorkspaceDatabase {

  workspacesService: WorkspacesService;
  workspaces: RQMWorkspace[] = new Array();
  wsnodes: WorkspaceFlatNode[] = new Array();


  setWorkspaceService(workspaceService: WorkspacesService) {
    this.workspacesService = workspaceService;
  }

  constructor() {
    this.wsnodes.push(new WorkspaceFlatNode(123, "test", true, 0, true));
    console.log("WorkspaceDatabase constructed");
  }

  initialData() {
    this.workspacesService.getWorkspaces().subscribe(
      {
        next(ws) {
          this.workspaces = ws;
          console.log(this.workspaces);
        },
        complete() {
          this.workspaces.forEach((ws) => {
            if (ws.workspace_id == null) {
              console.log(this.wsnodes);
              this.wsnodes.push(new WorkspaceFlatNode(ws.id, ws.name, true, 0, true))
            }
          });
          console.log("completed");
          console.log(this.wsnodes);
        }
      }
    );
  }

  getChildren(id: number): WorkspaceFlatNode[] | undefined {
    let children: WorkspaceFlatNode[] = new Array();
    console.log(this.workspaces);
    this.workspaces.forEach((ws) => {
      if (ws.workspaceId == id) {
        ws.workspaces.forEach((innerWs) => {
          children.push(new WorkspaceFlatNode(innerWs.id, innerWs.name, true, 0, true))
        });
        ws.documents.forEach((doc) => {
          children.push(new WorkspaceFlatNode(doc.id, doc.name, false, 0, true))
        });
      }
    })
    return children;
  }


}

Ответы [ 2 ]

1 голос
/ 22 сентября 2019

Внутри метода complete(), this является текущим объектом, то есть объектом, переданным в качестве аргумента subscribe().Не компонент.

Используйте функции стрелок.

См. stackblitz.com / edit / angular-zkry2p для демонстрации:

// not working
of('hello 1').subscribe({
  next(prefix) {
    console.log(prefix + ' ' + this.name);
  }
});

// working
of('hello 2').subscribe(prefix => console.log(prefix + ' ' + this.name)
);

// also working
of('hello 3').subscribe({
  next: prefix => console.log(prefix + ' ' + this.name)
});
0 голосов
/ 22 сентября 2019

complete метод использует синтаксис функции, который имеет другой this.Вместо передачи функций вы можете использовать функцию стрелки, которая сохранит свойство this родительского элемента.

initialData() {
    this.workspacesService.getWorkspaces().subscribe(
      ws => { //<--- arrow function

          this.workspaces = ws;
          console.log(this.workspaces);
        },
     err => {
        },
     () => { //<--- arrow function
          this.workspaces.forEach((ws) => {
            if (ws.workspace_id == null) {
              console.log(this.wsnodes);
              this.wsnodes.push(new WorkspaceFlatNode(ws.id, ws.name, true, 0, true))
            }
          });
          console.log("completed");
          console.log(this.wsnodes);
        }
    );
  }

Предполагая, что вы вызываете метод getChildren до завершения this.workspacesService.getWorkspaces(), this.workspaces не имеет никаких данных.Как только this.workspacesService.getWorkspaces() завершится, только тогда будет заполнен массив workspaces.

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