Angular — данные не загружаются без ручного обновления

#javascript #angular #typescript #rest #angular-ui-router

#javascript #angular #typescript #отдых #angular-пользовательский интерфейс-маршрутизатор

Вопрос:

У меня есть компонент, который импортирует две модели, Application модель и DataType модель. Одно приложение может иметь много типов данных. Целью этого компонента является обработка формы для добавления нового приложения с типами данных, которые выбираются из выпадающего списка. Приложение Angular использует вызовы REST для создания таких объектов. В серверной части Application — это одна таблица, DataTypes — это другая таблица и Application_DataTypes третья (связующая) таблица. Способ, которым это работает, заключается в том, что я вызываю метод GET для извлечения и перечисления всех типов данных, чтобы их можно было выбрать. Как только application_name и description заполнены, и выбраны типы данных, для приложения вызывается метод POST, я получаю ответ с идентификатором объекта, именем и описанием. Затем я делаю второй вызов POST application_datatypes , который вложен в ответ post приложения. Я делаю это, чтобы я мог извлекать application_id и использовать его при вставке в таблицу application_datatypes ссылок. После нажатия кнопки Сохранения приложение перенаправляется обратно на страницу, на которой есть список всех приложений и их подробная информация. Все работает по назначению, за исключением того, что после нажатия кнопки сохранения и отображения списка приложений типы данных остаются пустыми до тех пор, пока не будет выполнено обновление вручную или f5.

Соответствующий кодекс application.component.ts

 this.applicationService.createApplication(this.username, this.application).subscribe (
  response => {
    this.newApplication = Object.values(response)[0];
    this.applicationDataTypes.forEach(item => {
      if (item.checked) {
        this.appData = new AppData({appId: Object.values(response)[0], dataTypeId: item.dataTypeId});
        this.appDatas.push(this.appData);
      }
     });

    this.appDatas.forEach(item => {
      this.applicationService.createAppDataType(this.username, item).subscribe (
        data => console.log(data)
      );
    });
  },
  data => console.log(data),
);
this.router.navigate([`main-content/${this.userName}/destList`]);
 

Весь код для application.component.ts

 import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AppData } from '../models/app-data.model';
import { ApplicationDataType } from '../models/application-data-type.model';
import { Application } from '../models/application.model';
import { Datatype } from '../models/datatype.model';
import { BasicAuthenticationService } from '../service/basic-authentication.service';
import { ApplicationDataService } from '../service/data/application-data.service';


@Component({
  selector: 'app-application',
  templateUrl: './application.component.html',
  styleUrls: ['./application.component.css']
})
export class ApplicationComponent implements OnInit {

  constructor(
    private applicationService: ApplicationDataService,
    private route: ActivatedRoute, private router: Router,
    private basicAuthenticationService: BasicAuthenticationService) { }

  username: string;
  appId: number;
  dataTypeId: number;
  application: Application;
  appData: AppData;
  appDatas: AppData[];
  datatypes: Datatype[];
  checkedDatatypes: Datatype[];
  hide = true;
  exists = false;
  appDataId;
  applicationDataType: ApplicationDataType;
  applicationDataTypes: ApplicationDataType[];
  newApplication: number;
  userName = localStorage.getItem('userName');
  isApplicationInvalid = false;
  WarningMessage = 'Application Name and Description must be filled out!';

  counter = 0;

  ngOnInit(): void {
    this.username = this.basicAuthenticationService.getAuthenticatedUser();
    this.appId = this.route.snapshot.params.id;
    this.application = new Application(this.appId, '', '', '');
    this.applicationDataTypes =  [];
    this.appDatas = [];

    // tslint:disable-next-line:triple-equals
    if (this.appId != 0) {
      this.applicationService.retrieveApplication(this.username, this.appId).subscribe(
        data => this.application = data
      );

      this.applicationService.retreiveAllDataTypesByAppId(this.username, this.appId).subscribe(
        data => this.checkedDatatypes = data
      );

      this.applicationService.retreiveAllDatatypes(this.username).subscribe(
        data => this.datatypes = data
      );
    }

    this.applicationService.retreiveAllDatatypes(this.username).subscribe(
      data => this.datatypes = data
    );
  }

  getDatatypes = () => {
    // tslint:disable-next-line:triple-equals
    if (this.counter == 0) {
      // tslint:disable-next-line:triple-equals
      if (this.appId != 0){
        this.datatypes.forEach(item => {
          this.applicationDataType = new ApplicationDataType(this.route.snapshot.params.id, item.dataTypeId, item.description, false);
          const datatype = this.checkedDatatypes.find(y => y.description === item.description);
          if (datatype) {
            this.applicationDataType.checked = true;
            this.applicationDataTypes.push(this.applicationDataType);
          } else {
            this.applicationDataType.checked = false;
            this.applicationDataTypes.push(this.applicationDataType);
          }
        });
      } else {
        this.datatypes.forEach(item => {
          this.applicationDataType = new ApplicationDataType(this.route.snapshot.params.id, item.dataTypeId, item.description, false);
          this.applicationDataTypes.push(this.applicationDataType);
        });
      }
      this.counter   ;
    }
  }

  uncheck = dataType => {
    const index = this.applicationDataTypes.indexOf(dataType);
    this.applicationDataTypes[index].checked = !this.applicationDataTypes[index].checked;
  }

  saveApplication = () => {
    // tslint:disable-next-line:triple-equals
    if (this.application.appName != '' amp;amp; this.application.appDesc != '') {
      // tslint:disable-next-line:triple-equals
      if (this.appId == 0) {
        this.applicationService.createApplication(this.username, this.application).subscribe (
          response => {
            this.newApplication = Object.values(response)[0];
            this.applicationDataTypes.forEach(item => {
              if (item.checked) {
                this.appData = new AppData({appId: Object.values(response)[0], dataTypeId: item.dataTypeId});
                this.appDatas.push(this.appData);
              }
             });

            this.appDatas.forEach(item => {
              this.applicationService.createAppDataType(this.username, item).subscribe (
                data => console.log(data)
              );
            });
          },
          data => console.log(data),
        );
      }
      else {
        this.applicationService.updateApplication(this.username, this.appId, this.application).subscribe (
          data => console.log(data)
        );

        this.applicationDataTypes.forEach(item => {
          if (item.checked) {
            if (!this.checkedDatatypes.find(z => z.description === item.datatypeDescription)){
              this.appData = new AppData({appId: this.appId, dataTypeId: item.dataTypeId});
              this.appDatas.push(this.appData);
            }
          }
         });

        this.appDatas.forEach(item => {
          this.applicationService.createAppDataType(this.username, item).subscribe (
            data => console.log(data)
          );
        });

        this.applicationDataTypes.forEach(item => {
          if (!item.checked) {
            if (this.checkedDatatypes.find(z => z.description === item.datatypeDescription)){
              this.applicationService.deleteAppDataType(this.username, this.appId, item.dataTypeId).subscribe(
                response => {
                  console.log(response);
                }
              );
            }
          }
         });
      }
      this.router.navigate([`main-content/${this.userName}/destList`]);
    }
    else {
      this.isApplicationInvalid = true;
    }
  }

  CancelAction = () => {
    this.router.navigate([`main-content/${this.userName}/destList`]);
  }

  onHomePage = () => this.router.navigate([`main-content/${this.userName}/home`]);
}
 

applications.component.ts — это компонент, который отображает список приложений с их деталями.

 import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ModalService } from '../../modal/modal.service';
import { Application } from '../../models/application.model';
import { Datatype } from '../../models/datatype.model';
import { BasicAuthenticationService } from '../../service/basic-authentication.service';
import { ApplicationDataService } from '../../service/data/application-data.service';

@Component({
  selector: 'app-applications',
  templateUrl: './applications.component.html',
  styleUrls: ['./applications.component.css']
})
export class ApplicationsComponent implements OnInit {

  applications: Application[];
  datatypes: Datatype[];
  username: string;
  message: string;
  groupId = localStorage.getItem('groupId');
  appDeleteId: number;

  constructor(private applicationService: ApplicationDataService,
              private router: Router,
              private basicAuthenticationService: BasicAuthenticationService,
              private modalService: ModalService) { }

  ngOnInit(): void {
    this.refreshApplications();
    this.username = this.basicAuthenticationService.getAuthenticatedUser();
  }

  refreshApplications = () => {
    this.username = this.basicAuthenticationService.getAuthenticatedUser();
    this.applicationService.retreiveAllApplications(this.username).subscribe(
      response => {
        console.log(response);
        this.applications = response;
      }
    );
  }

  deleteApplication = appId => {
    console.log(`delete app ${appId}`);

    this.applicationService.deleteApplication(this.username, appId).subscribe(
      response => {
        console.log(response);
        this.message = `Application ${appId} was Successfully Deleted!`;
        this.refreshApplications();
      }
    );
  }

  updateApplication = appId => {
    console.log(`update app ${appId}`);
    this.router.navigate(['applications', appId]);
    this.applicationService.retreiveAllDataTypesByAppId(this.username, appId).subscribe(
      response => {
        console.log(response);
        this.datatypes = response;
      }
    );
  }

  openModal = (id, appId) => {
    this.modalService.open(id);
    this.appDeleteId = appId;
  }

  closeModal = (id, confDelete) => {
    this.modalService.close(id);
    if (confDelete) {
      this.deleteApplication(this.appDeleteId);
    }
  }
}
 

Комментарии:

1. Я предполагаю, что маршрут destList — это страница, на которой отображается список приложений? И эта страница не обновляется? Если да, то можете ли вы показать код и для этой страницы?

2. Вы предполагаете правильно, и он обновляется, но только с идентификатором приложения, именем и описанием, но не с типами данных

3. @Люк. Я добавил код, который вы запросили.