Angular 7 兄弟组件的共享服务从其他兄弟组件获取数据

Angular 7 shared service for siblings component to get data from other sibling

在我的 Angular 7 应用程序中,我有两个同级组件...配置器组件和自定义步进器组件。在配置器组件中,我有一些函数可以从我的 API 获取数据并计算一些值...我想在自定义步进器组件中显示计算值。

我创建了一个名为价格权重服务的服务,但我不确定将哪个代码移动到哪里以及如何从自定义步进器组件中的该服务获取值。

configurator.component.ts 有这个代码:

constructor(
        public dialog: MatDialog,
        private httpClient: HttpClient,
        private _snackBar: MatSnackBar,
        public priceWeight: PriceWeightService,
    ) { }

ngOnInit() {
        const httpOptions = {
            headers: new HttpHeaders({
                'Auth-token': 'somerandomstring',
            })
        };
    
        this.httpClient.get(`${environment.apiUrl}`, httpOptions).subscribe(
            (data) => {
                this.parseData(data);
                console.log('Izbrana konfig.:', this.selected);
                this.getTotalWeight();
                this.getTotalPrice();
            },
            (error) => {
                console.log('Error', error);
            }
        );
    
        // this.getData();
        this.openDialog();
    }
    
    parseData(data: any) {
        console.log(data);
        this.data = data;
    
        let i = 0;
    
        for (const step of data.steps) {
            if (step.subcategory.length === 0) {
                this.selected[i] = {
                    ident: step.ident,
                    name: step.name,
                    optionIdent: step.options[0].ident,
                    optionName: step.options[0].name,
                    optionPrice: step.options[0].price,
                    optionWeight: step.options[0].weight,
                    categoryType: step.category_type,
                };
            }
            i++;
        }
    }
    
    
    findElement(item) {
        return Object.values(this.selected).filter(e => e.optionIdent === item.ident).length > 0;
    }
    
    setOptionSelected(item, step) {
    
        if (Object.values(this.selected).filter(e => e.ident === step.ident).length > 0) {
    
            const selectedKey = Object.values(this.selected).findIndex(x => x.ident === step.ident);
            this.selected[selectedKey] = {'ident': step.ident, 'name': step.name, 'optionIdent': item.ident, 'optionName' : item.name, 'optionPrice' : item.price, 'optionWeight' : item.weight, 'categoryType' : step.category_type};
        } else {
    
            const totalLength = Object.keys(this.selected).length;
            this.selected[totalLength] = {'ident' : step.ident, 'name': step.name, 'optionIdent' : item.ident, 'optionName' : item.name, 'optionPrice' : item.price, 'optionWeight' : item.weight, 'categoryType' : step.category_type};
        }
        this.getTotalWeight();
        this.getTotalPrice();
    }
    
    setOptionSubCatSelected(item, step, subcategory) {
    
        if (step.category_type === 1 && (Object.values(this.selected).filter(e => e.ident === subcategory.ident && e.optionIdent === item.ident).length > 0 ) ) {

            const index: number = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident && x.optionIdent === item.ident);
            if (index !== -1) {
                this.selected.splice(index, 1);
            }
        } else {
    
            if (Object.values(this.selected).filter(e => e.ident === subcategory.ident).length > 0) {
    
                const selectedKey = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident);
                this.selected[selectedKey] = {
                    'ident': subcategory.ident,
                    'name': subcategory.name,
                    'optionIdent': item.ident,
                    'optionName' : item.name,
                    'optionPrice' : item.price,
                    'optionWeight' : item.weight,
                    'categoryType' : subcategory.category_type
                };
            } else {
                const totalLength = Object.values(this.selected).length;
                this.selected[totalLength] = {
                    'ident' : subcategory.ident,
                    'name': subcategory.name,
                    'optionIdent' : item.ident,
                    'optionName' : item.name,
                    'optionPrice' : item.price,
                    'optionWeight' : item.weight,
                    'categoryType' : subcategory.category_type
                };
            }
        }
        this.getTotalWeight();
        this.getTotalPrice();
    }
    
    setCheckSelected(item, step, subcategory) {
    
        if (step.category_type === 1 && (Object.values(this.selected).filter(e => e.ident === subcategory.ident && e.optionIdent === item.ident).length > 0 ) ) {
    
            const index: number = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident && x.optionIdent === item.ident);
            if (index !== -1) {
                this.selected.splice(index, 1);
            }
    
        } else {
            const totalLength = Object.keys(this.selected).length;
            this.selected[totalLength] = {
                'ident' : subcategory.ident,
                'name': subcategory.name,
                'optionIdent' : item.ident,
                'optionName' : item.name,
                'optionPrice' : item.price,
                'optionWeight' : item.weight,
                'categoryType' : subcategory.category_type
            };
        }
        this.getTotalWeight();
        this.getTotalPrice();
    }
    
    getTotalPrice() {
        let totalPrice = 0;
        console.log('Price start:', totalPrice);
        for (const item of this.selected) {
            if (item.optionPrice) {
                totalPrice += Number(item.optionPrice);
                console.log('Price now:', totalPrice);
            }
        }
        console.log('Total price:', totalPrice);
        return totalPrice;
    }
    
    getTotalWeight() {
        let totalWeight = 0;
        console.log('Weight start:', totalWeight);
        for (const item of this.selected) {
            if (item.optionWeight) {
                totalWeight += Number(item.optionWeight);
                console.log('Weight now:', totalWeight);
            }
        }
        console.log('Total weight:', totalWeight);
        return totalWeight;
    }

custom-stepper.component.ts is this:

中的代码
import { Component } from '@angular/core';
import { CdkStepper } from '@angular/cdk/stepper';

import { PriceWeightService } from '../_services/price-weight.service';

@Component({
  selector: 'app-custom-stepper',
  templateUrl: './custom-stepper.component.html',
  styleUrls: ['./custom-stepper.component.scss'],
    providers: [{provide: CdkStepper, useExisting: CustomStepperComponent}],
})

export class CustomStepperComponent extends CdkStepper {

    constructor(
        public priceWeight: PriceWeightService
    ){}

    onClick(index: number): void {
      this.selectedIndex = index;
    }
}

这是 custom-stepr 的 html 我不想显示这些值的方式:

  <footer>
    <mat-toolbar>
      <h2>Step {{selectedIndex + 1}}/{{_steps.length}}</h2>
      <span class="fill-space"></span>
      <p class="mat-small"><strong>Total weight:</strong> {{ totalWeight | number: '1.2':'sl' }} KG</p>
      <span class="fill-space"></span>
      <p class="mat-small"><strong>Total price:</strong> {{ totalPrice | currency: 'EUR':'symbol':'4.2-2':'sl' }}</p>
      <span class="fill-space"></span>
      <button [ngClass]="selectedIndex > 0 ? 'noBtn': ''" mat-raised-button color="primary" class="naslednji-korak" [disabled]="(selectedIndex + 1)>_steps.length" cdkStepperNext>Begin configuration</button>
      <button [ngClass]="selectedIndex == 0 ? 'noBtn': ''" mat-raised-button color="secondary" class="naslednji-korak" [disabled]="selectedIndex == 0" cdkStepperPrevious>Previous step</button>
      <button [ngClass]="selectedIndex == 0 ? 'noBtn': ''" mat-raised-button color="primary" class="naslednji-korak" [disabled]="(selectedIndex + 1)==_steps.length" cdkStepperNext>Next step</button>
      <button [ngClass]="(selectedIndex + 1)<_steps.length ? 'noBtn': ''" mat-raised-button color="primary" class="naslednji-korak" [disabled]="(selectedIndex + 1)<_steps.length" (click)="reset()">Submit order</button>
    </mat-toolbar>
  </footer>

我已使用此代码添加服务:

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

@Injectable({
  providedIn: 'root',
})
export class PriceWeightService {
  weight = 0;
}

在服务中创建属性:

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

@Injectable({
  providedIn: 'root',
})
export class PriceWeightService {
  weight = 0;
}

将服务注入两个组件

constructor(private priceWeight: PriceWeightService){}

通过您的配置器组件在服务上设置一个属性,像这样

this.priceWeight.weight = this.getTotalWeight();

服务是单例的,因此这将为注入服务的任何其他组件更新 属性。

要在您的步进器组件中使用服务 属性 ,请创建服务 public,或创建一个 getter。

constructor(public priceWeight: PriceWeightService){}
<p>{{priceWeight.weight}}</p>

constructor(private priceWeight: PriceWeightService){}

get weight(){
  return this.priceWeight.weight;
}
<p>{{weight}}</p>

你需要的具体代码

服务

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

@Injectable({
  providedIn: 'root',
})
export class PriceWeightService {
  price = 0;
  weight = 0;
}

configurator.component.ts

this.httpClient.get(`${environment.apiUrl}`, httpOptions).subscribe(
            (data) => {
                this.parseData(data);
                console.log('Izbrana konfig.:', this.selected);
                this.priceWeightService.weight = this.getTotalWeight();
                this.priceWeightService.price = this.getTotalPrice();
            },
            (error) => {
                console.log('Error', error);
            }
        );

custom-stepper.component.ts

  constructor(private priceWeight: PriceWeightService){}

  get totalWeight(){
    return this.priceWeight.weight;
  }

  get totalPrice(){
    return this.priceWeight.price;
  }