简体   繁体   中英

Passing Between Components Angular

I currently have 3 components stacked like this:

<app-header></app-header>
<app-body></app-body>
<app-footer></app-footer>

However I want to switch it so that the footer and body positioning is different like below:

<app-header></app-header>
<app-footer></app-footer>
<app-body></app-body>

Once I change the placement of and the footer is no longer loading anything from the dataservice. Constructor inside footer.component.ts:

constructor(private dataService: DataService) {
    //subscribing the the dataService so that we can display its contents
    this.dataService.currentNoms.subscribe(noms => {this.nominations.push(noms);});
  }

Constructor inside body.component.ts:

  constructor(private http: HttpClient, private dataService: DataService) { 
    //adding the nominations to my dataService to use between components
    this.dataService.addNominations(this.nominations);
  }

data.Service.ts:

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

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

  private finalNoms = new BehaviorSubject<any>([]);
  currentNoms = this.finalNoms.asObservable();

  constructor() { 
    this.addNominations(this.nominations);
  }

  addNominations(nom: Object){
    this.finalNoms.next(nom);
  }

}

I tried swapping the contents of the constructor but that doesnt seem to be helping. Anyone know what im doing wrong? New to Angular, Thank you in advance!

It stands to reason that your BodyComponent is being loaded after your Footer component, and so this line of code has not been executed by the time your Footer component requests the data:

this.dataService.addNominations(this.nominations);

I would suggest moving the above line of code into the costructor of the Data Service, so that the data is always available, once the service becomes available.

Alternatively, you could leverage rxjs Subjects in your data service to asynchoronously set and retrieve the data:

// In data.service.ts
nominations = new BehaviorSubject([...]);
nominations$ = this.nominations.asObservable();

addNomination(nom) {
    const noms = this.nominations.value;
    noms.push(nom);
    this.nominations.next(noms);
}
// In body.component.ts
nominations: any[]; // Or the interface/type you're using

constructor(private dataService: DataService) {
    this.dataService.nominations$.subscribe(noms => this.nominations = noms);
}

addNomination(nom: any) {
   this.dataService.addNomination(nom);
}
// In footer.component.ts
nominations: any[];

constructor(private dataService: DataService) {
    this.dataService.nominations$.subscribe(noms => this.nomations = noms);
}

I think that you can achieve if you eclosed yours component in a div flex

<div [style]="display:flex;flex-direction: column"
     *ngIf="{order:orderService.currentNoms|async} as order" >
  <app-header [style.order]="order.order?order.order[0]:null"></app-header>
  <app-body [style.order]="order.order?order.order[1]:null"></app-body>
  <app-footer [style.order]="order.order?order.order[2]:null"></app-footer>
</div>

You main.cmponent

  constructor(public orderService:OrderService){}

Your service

export class OrderService {

  private finalNoms = new BehaviorSubject<any>([]);
  currentNoms = this.finalNoms.asObservable();

  setOrder(order:any[])
  {
    this.finalNoms.next(order)
  }

Inside any component in ngOnInit

 this.orderService.setOrder([1,3,2]) //change the order

A fool stackblitz

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