Home > front end >  My offerflow is Angular11, can't get value 1 or 2 in html
My offerflow is Angular11, can't get value 1 or 2 in html

Time:03-06

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:

  1. casing wrong on ngSwitchCase directive
  2. OnPush change detection not running correctly, async pipe resolves
  3. ng-template doesn't render to DOM. it's a template for use elsewhere. use ng-container instead.
  • Related