简体   繁体   中英

How do I update state object when an event is emitted from an outside component using ngrx with Angular 6?

I have a footer component with a "Save" button that is always visible in my Angular 6 app - it is a core component that never destroys unless the app is destroyed. Each page of the app is a different section in saving a Product, so for example a "General Info" section, "Pricing" section, "Quantity" section, and so forth. When I progress through my app, if I click the Save button, at any time, it should save the current state of the Product object.

I have a Product object that looks like this:

export interface Product {
    id: number;
    name: string;
    price: number;
    qty: number;
}

My "General Info" feature page looks like this:

constructor(private store: Store<fromProduct.State>) {}

ngOnInit() {
    this.store.dispatch(new LoadAction());
    this.product$ = this.store.pipe(select(fromProducts.getProduct));
}

This loads the product just fine, I see all of the values from the product$ observable in my view. However, I don't know how to "pass" the loaded product object to the footer component to save the state.

My footer component looks like this:

// Markup
<button (click)="saveProduct($event)">Save</button>

// Component
import * as productActions from '../../product/state/actions';

...

saveProduct(product: Product) {
    this.store.dispatch(new productActions.SaveProductAction(product));
}

I know $event is linked to nothing - that is what my question is. How can I get the Product object from the "General Info" component into the footer component via ngrx ?

Thanks!

I think that your footer should not hold the save logic, since it's just a unique trigger for multiple actions.

I'd advise you to propagate the Save button click event to where your forms are.

If the form is a direct parent or sibling, then you could do it simply with @Input() and @Output() , if it's not then you can use a service to share an Observable between your forms and your button as follows:

@Injectable()
export class EventService{

  private subject= new Subject<any>();

  saveButtonClicked = this.subject.asObservable();

  constructor() { }

  saveButtonClick() {
    this.subject.next();
  }
}

Footer template:

<button (click)="onSaveClick()">Save</button>

Footer TypeScript:

onSaveClick() {
   this.eventService.saveButtonClick();
}

Your different forms:

this.eventService.saveButtonClicked.subscribe(res => {
   // Your save logic
});

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