首页 > 解决方案 > 在 Angular 9 中,如何更新组件的数据字段以在 DOM 中显示而不重新实例化它?

问题描述

我对 Angular 9 还很陌生。我有一个程序,用户输入一个名称 - 在提交时 - 发送一个 POST HTTP 请求并存储该名称。然后,我有一个不相关的子标题组件,它列出了使用 ngOnInit() 的 GET HTTP 请求存储的名称。但是,我需要子标题在每次输入新列表时动态更新该名称列表,而不仅仅是在组件实例化时。

我不确定如何进行。我确信我可以简单地添加一个按钮来获取和更新所述列表,但尝试更动态的东西。提前致谢!

//SERVICE.TS...

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { NewList } from './new-list.model';

import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ListService {

  createdLists: NewList[] = [];

  constructor(private http: HttpClient) { }

  createList(postData) {
    return this.http
      .post(
        'API_KEY',
        postData
      );
  }

  getLists() {
    return this.http
      .get<NewList>(
        'API_KEY'
      ).pipe(map(responseData => {
            const responseArray: NewList[] = [];
            for (const key in responseData) {
              responseArray.push(responseData[key])
            }
            return responseArray;
          })
        );
  }
}




// NEW-LIST-MENU.TS (USER ENTERS A NAME)...

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Router } from '@angular/router';

import { ListService } from 'src/app/shared/list.service';
import { NewList } from 'src/app/shared/new-list.model';
import { UIService } from 'src/app/shared/ui.service';

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


  constructor(private listService: ListService,
              private uiService: UIService,
              private router: Router) { }

  ngOnInit(): void {
  }

  onSubmit(form: NgForm) {
    const listName = form.value.listname;
    const newListObj = new NewList(listName, []);
    
    this.listService.createList(newListObj)
      .subscribe(() => {
        this.router.navigate(['']);
      });

    const lists = this.listService.updateLists(newListObj);
    
    
    form.reset();
  }

  onCancel() {
    this.router.navigate(['']);
  }

}





// SUB-HEADER.TS...

import { Component, OnInit, Output } from '@angular/core';
import { Router } from '@angular/router';

import { ListService } from 'src/app/shared/list.service';
import { NewList } from 'src/app/shared/new-list.model';

import { faWindowClose } from '@fortawesome/free-solid-svg-icons';
import { faPlusCircle } from '@fortawesome/free-solid-svg-icons';
import { faList } from '@fortawesome/free-solid-svg-icons';
import { faSignOutAlt } from '@fortawesome/free-solid-svg-icons';

import { Subject } from 'rxjs';


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

  createdLists: NewList[];

  faWindowClose = faWindowClose;
  faPlusCircle = faPlusCircle;
  faList = faList;
  faSignOutAlt = faSignOutAlt;

  @Output() closeSub = new Subject();

  constructor(private listService: ListService, 
              private router: Router) { }

  ngOnInit(): void {
    this.listService.getLists().subscribe((responseData) => {
      this.createdLists = responseData;
    });
  }

  onCloseSelect() {
    this.closeSub.next();
  }

  onNewListSelect() {
    this.onCloseSelect();
    this.router.navigate(['new-list-menu']);
  }

  onLogOutSelect() {

  }

}```

标签: javascriptangulartypescript

解决方案


您可以通过多种方式完成此操作,因为这些组件彼此不相关,您可以引入状态服务并使用可观察对象。请参阅下面可能的解决方案

  1. 创建一个新的状态服务 ListStateService

     export class ListStateService {
         private listData = new BehaviorSubject<NewList >({} as NewList);       
         listData$ = this.listData .asObservable();
     }
    
  2. 将 ListStateService 注入 NewListMenuComponent

在 onSubmit 中,更新后,

 const lists = this.listService.updateLists(newListObj);
    this.listData .next(lists );
  1. 将 ListStateService 注入 SubHeaderComponent 在 ngOnInit() 中,订阅 ListStateService.listData$,在这里您将获得更改的值

推荐阅读