Angular 6:将数据添加到另一个组件后更新一个组件中的表

Dom*_*ann 3 components interaction angular

我在 Angular 6 中创建了一个包含两个组件的单页面应用程序。它们通过数据服务与网络服务器进行通信。一个组件列出所有项目,另一个组件允许用户将项目添加到该列表。有趣的是,通过在删除列表组件中的一项后调用 getItems,它会刷新列表,而从创建组件调用 get MatTableDataSource 属性则不会刷新列表。任何积分都非常感激。谢谢。

列表组件:

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
import { MatTableDataSource } from '@angular/material/table';

import { Item } from '../items.model';

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

  public items = new MatTableDataSource<Item>();
  private displayedColumns = ['name', 'status', 'actions'];

  constructor(private data: DataService) { }

  ngOnInit() {
    this.getItems();
    console.log('New list page initialized');
  }

  getItems() {
    this.data.getItems().subscribe( (items: Item[]) => {
      this.items.data = items;
      console.log(this.items);
    });
  }

  deleteItem(id) {
    this.data.deleteItem(id).subscribe( (res) => {
      console.log(res);
      this.getItems();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

创建组件:

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
import { ListComponent } from '../list/list.component';
import { Item } from '../items.model';

import { MatSnackBar } from '@angular/material';

import {FormGroup, FormBuilder, Validators } from '@angular/forms';


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

  createForm: FormGroup;

  constructor(private list: ListComponent ,private data: DataService, private fb: FormBuilder, private snackBar: MatSnackBar) {
    this.createForm = this.fb.group( {
      name: ['', Validators.required],
      status: ['']
    });
   }

  ngOnInit() {
  }

  addItem(name) {
    this.data.postItem(name).subscribe( (res) => {
      console.log(res);
      this.data.getItems().subscribe( (item: Item[])  => {
        this.list.items.data = item;
      })
      this.snackBar.open('Your item was succesfully added to the shopping list.', 'Cool!', {
        duration: 3000
      });
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

数据服务:

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

  API_URL: string = 'https://cookie-munchies.herokuapp.com/api/items';

  constructor(private http : HttpClient) { }

  getItems(){
    return this.http.get(this.API_URL);
  }

  postItem(name){
    let item = {
      name: name,
    };

    return this.http.post(this.API_URL, item);
  }

  deleteItem(id) {
    return this.http.delete(`${this.API_URL}/${id}`);
  }

  updateItem(id, item: Item) {
    // TODO: write update function
    return this.http.put(`${this.API_URL}/${id}`, item);
  }
}
Run Code Online (Sandbox Code Playgroud)

Rin*_*wat 5

我从您的问题中了解到,您需要从组件添加数据并将其显示为其他组件列表中的更新内容。要实现这一点,您可以使用 rxjs i,e subject 的功能。

在您的数据服务中:

//declare a subject instance

private subject =new Subject<any>();

//Value is any string message or boolean value
//this will notify that you have added or deleted the data successfully and you //want other component to listen that

sendNotification(value:any)
{
    this.subject.next({text:value});
}

//this will be subscribed by the listing component which needs to display the //added/deleted ie updated list.

getNotification(){
    return this.subject.asObservable();
}

//In the method which you are saving data either by http client or in a list. In //its success call sendNotification method.

postItem(name){
    let item = {
      name: name,
    };

    return this.http.post(this.API_URL, item).pipe(
      map((data=>{
        this.sendNotification(true);
        }
      }
    )));
  }
 deleteItem(id) {
    return this.http.delete(`${this.API_URL}/${id}`).pipe(
      map((data=>{
        this.sendNotification(true);
        }
      }
    )));;
  }
Run Code Online (Sandbox Code Playgroud)

在您的列表组件 ts 中添加以下代码:

// create a field of type Subscription
subscription:Subscription

//then add the following code in constructor:

constructor(private data: DataService){
this.subscription=this.dataService.getNotification().subscribe(data=>{
      if(data)
      {
        this.getItems();
      }
    });
}
Run Code Online (Sandbox Code Playgroud)

它将正常工作,并且会在每次添加和删除时更新您的列表。

组件关闭后请务必取消订阅主题,以避免列表组件中出现不必要的内存泄漏。

ngOnDestroy():void
  {
      this.subscription.unsubscribe();
  }

Run Code Online (Sandbox Code Playgroud)