My task: The received value from service 1 or 2, depending on the value, change the styles in the html component. Using the ng-switch directive, I expect to compare the value received from the object with the specified template value. Styles are not applied. The main problem is that the styles are not applied
My component:
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, Self } from '@angular/core';
import { ConfigService, IProductListItem, SliderValueOptions } from 'common-modules';
import { Router } from '@angular/router';
import { debounceTime, filter, takeUntil, tap } from 'rxjs/operators';
import { NgOnDestroy } from '../../core/services/destroy.service';
import { BehaviorSubject } from 'rxjs';
import { OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-product-item',
templateUrl: './product-item.component.html',
styleUrls: ['./product-item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [NgOnDestroy],
})
export class ProductItemComponent implements OnInit, OnDestroy {
@Input() product: IProductListItem;
@Input() doubleClickEnabled: boolean;
// tslint:disable-next-line:no-output-on-prefix
@Output() onAddToCart = new EventEmitter<any>();
themeProperties: number;
visibility: boolean = false;
constructor(private _router: Router, private _config: ConfigService, @Self() private onDestroy$: NgOnDestroy) {}
ngOnInit() {
this._config.marketplaceConfig.pipe(takeUntil(this.onDestroy$)).subscribe((config) => {
this.themeProperties = config.structure?.theme;
});
}
}
My html:
<mat-card >
<div [ngSwitch]="themeProperties">
<ng-template *ngswitchcase="2">
{{ themeProperties }}
<mat-card id="cardbackground">
<a (click)="redirectToProduct(product)" (dblclick)="doubleClicked(product)">
<div
style="display: none"
*ngIf="product.priceWithDiscount && product?.promoIndividual?.percentDiscount"
>
-{{ product?.promoIndividual?.percentDiscount }}%
</div>
<!-- <b2b-modern-image mat-card-image [src]="product.photos[0]"></b2b-modern-image> -->
<img [src]="product.photos" alt="" />
<mat-card-content [class.has-padding-top]="product && product['discount']">
<div >супер скидка</div>
<div *ngIf="product && product['discount']" >-{{ product['discount'] }}%</div>
<div
*ngIf="product && product.promoIndividual && product?.promoIndividual?.percentDiscount"
>
-{{ product?.promoIndividual?.percentDiscount }}
%
</div>
<ng-template #defaultPrice>
<!-- <span >{{product.price}} ₽</span>-->
</ng-template>
<div >
<ngx-stars color="#ffd700" [readonly]="true" [initialStars]="product.rating || 0"> </ngx-stars>
<span >{{ product.views || 0 }} отзывов</span>
</div>
<h3 [matTooltip]="product?.feed" matTooltipPosition="above">
{{ product | localize: 'name' }}
</h3>
<div >
<div
*ngIf="product.priceWithDiscount && product.priceWithDiscount != product.price; else defaultPrice"
>
<span >{{ product.price }}₽</span>
</div>
<p >{{ (product.priceWithDiscount || 0).toFixed(1) }}₽</p>
</div>
</mat-card-content>
</a>
<mat-card-footer >
<a routerLink="/confirm-order" [queryParams]="{ products: product.id }" mat-raised-button color="primary">
Купить сейчас
</a>
<button mat-button color="primary" (click)="addToCart(product)">
<mat-icon>add_shopping_cart</mat-icon>
</button>
</mat-card-footer>
</mat-card>
</ng-template>
</div>
</mat-card>
CodePudding user response:
The spelling of the template switch statement is case sensitive, should be *ngSwitchCase
, and its value should have a '
around it, as the value is expected to be a 'match expression'.
So change your statements to this layout, and all should work:
<ng-template *ngSwitchCase="'2'">
also because you are using ChangeDetectionStrategy.OnPush
you need to trigger the change detection manually for the ngSwitch.
Here is a working example.
constructor(private _router: Router, private _config: ConfigService, @Self() private onDestroy$: NgOnDestroy, private cdr: ChangeDetectorRef) {}
ngOnInit() {
this._config.marketplaceConfig.pipe(takeUntil(this.onDestroy$)).subscribe((config) => {
this.themeProperties = config.structure?.theme;
this.cdr.detectChanges(); // <=== here, after setting the value
});
}
CodePudding user response:
change component to:
themeProperties$: Observable<number>;
...
ngOnInit() {
this.themeProperties$ = this._config.marketplaceConfig.pipe(map((config) => config.structure?.theme))
}
change template to:
<div [ngSwitch]="themeProperties$ | async">
<ng-container *ngSwitchCase="2">
....
</ng-container>
issues:
- casing wrong on
ngSwitchCase
directive OnPush
change detection not running correctly,async
pipe resolvesng-template
doesn't render to DOM. it's a template for use elsewhere. useng-container
instead.