简体   繁体   中英

How to manage objects efficiently between components in Angular?

I am a new bee to Angular and learning a lot from this forum. I have a scenario as below Component 1 - ObjectA created and passed on to Component 2 on Form Submit Component 2 - Makes changes to ObjectA and Sends back to Component1 (I am using ngOnChange event to listen to the change in the object) HTML is updated in Component based on the changes

Few Code snippets Component 1

Object1: Array<SomeInterface>;
@Input() Obj: Object;
@Output() Search: EventEmitter<any> = new EventEmitter<any>();

OnSubmit() {
  this.Submit.emit(this.Obj);
 }

ngOnChanges(changes: SimpleChanges): void {
  this.Object1 = this.Obj
}

Component 2

@Input() Obj: Array<SomeInterface> = [];

Submit(valueEmitted: Payload) {
// Changes made to object

}

I am working on Angular 13

在此处输入图像描述

As mentionned in the comments above, this is a way you could potentially organise your 2 components, this even removes the need to passing some of the filters or need for that

带有父组件的结构

Basically in the above, your component 1 & component 2 are "dumb component" they just display UI based on @Input() and throw events on @Output()

Your component 3 is doing all the heavy lifting here and handling the data, this should get rid of the need to pass on some of the data between comp 1 & 2, and solve some of the CD concern I've expressed earlier

---- Edit ---

@Sam K

import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';

import { PuppiesModule } from './puppies.module';
import { Puppy } from './puppy.model';

@Injectable({ providedIn: PuppiesModule })
export class PuppiesStoreService {
  // Make _puppiesSource private so it's not accessible from the outside, 
  // expose it as puppies$ observable (read-only) instead.
  // Write to _puppiesSource only through specified store methods below.
  private readonly _puppiesSource = new BehaviorSubject<Puppy[]>([]);

  // Exposed observable (read-only).
  readonly puppies$ = this._puppiesSource.asObservable();

  constructor() {}

  // Get last value without subscribing to the puppies$ observable (synchronously).
  getPuppies(): Puppy[] {
    return this._puppiesSource.getValue();
  }

  private _setPuppies(puppies: Puppy[]): void {
    this._puppiesSource.next(puppies);
  }

  addPuppy(puppy: Puppy): void {
    const puppies = [...this.getPuppies(), puppy];
    this._setPuppies(puppies);
  }

  removePuppy(puppy: Puppy): void {
    const puppies = this.getPuppies().filter(p => p.id !== puppy.id);
    this._setPuppies(puppies);
  }

  adoptPuppy(puppy: Puppy): void {
    const puppies = this.getPuppies().map(p =>
      p.id === puppy.id ? new Puppy({ ...p, ...{ adopted: true } }) : p
    );
    this._setPuppies(puppies);
  }
}

This would be a nice example where the service is handling the state but also making the api call.

You could tweak around to :

  • Not make it provided in 'root' but in the module that contains both your component 1 & component 2 ( if they are in the same module, otherwise leave it as providedIn: 'root'
  • You could just hold and modify the object, if you don't want to do the http call for your results.

Here is another ressource that you might want to look https://dev.to/avatsaev/simple-state-management-in-angular-with-only-services-and-rxjs-41p8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM