Angular 7为兄弟组件提供共享服务,从其他兄弟组件获取数据



在我的Angular 7应用中,我有两个兄弟组件…配置器组件和自定义步进组件。在配置器组件中,我有一些函数从我的API获取数据并计算一些值…我想在自定义步进元件中显示计算值。

我已经创建了一个名为price-weight service的服务,但我不确定将哪个代码移动到哪里以及如何在自定义步进组件中从该服务获取值。

configuration .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;
}
}

这是自定义步进的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;
}

最新更新