簡體   English   中英

如何在 Angular(v14) 中更新@ViewChildren(或@ContentChildren)的 styles

[英]How to update the styles of @ViewChildren (Or @ContentChildren) in Angular(v14)

我正在嘗試創建一個輪播組件,該組件根據它將獲得的任何大小列表具有 n 個子組件。 我希望父項(旋轉木馬)控制子項的樣式,因為它操縱列表的大小並跟蹤索引以圍繞旋轉木馬旋轉項目並相應地設置樣式。 將有按鈕來控制此行為。 旋轉木馬的例子

我正在嘗試應用 styles 並使功能正常工作,但似乎無法通過使用視圖子項和模板引用獲取元素引用的查詢列表來訪問 styles(我最初也嘗試使用內容子項,模板設置正確)。 如果我在子級別注入元素引用和渲染器,我可以更改它們,但我不想在這里這樣做。 我收到錯誤: TypeError: Cannot read properties of undefined (reading 'style')但是當我從子級別做完全相同的事情時卻沒有。

我做錯了嗎? 如何從父母的 @ViewChildren() 更改列表中的孩子 styles?

父組件(carousel.component.html)

  <div class="caro-body">
    <h3 class="caro-body__title">Carousel Title</h3>
    <div class="caro-body__items">
      <app-upcoming-card
      #caroItem
      *ngFor="let card of list; let i = index"
      ></app-upcoming-card>
    </div>
  </div>

(旋轉木馬.component.ts)

import {
  Component,
  OnInit,
  AfterViewInit,
  Renderer2,
  ViewChildren,
  QueryList,
  ElementRef,
} from '@angular/core';
import { UpcomingCardComponent } from '../upcoming-card/upcoming-card.component';

@Component({
  selector: 'app-carousel',
  templateUrl: './carousel.component.html',
  styleUrls: ['./carousel.component.scss'],
})
export class CarouselComponent implements OnInit, AfterViewInit {
  @ViewChildren('caroItem') caroItems: QueryList<ElementRef<UpcomingCardComponent>>

  list = [
    { billName: 'Rent', billAmount: 850, billDate: Date.now() },
    { billName: 'Groceries', billAmount: 250, billDate: Date.now() },
    { billName: 'Internet', billAmount: 80, billDate: Date.now() },
    { billName: 'Phone', billAmount: 45, billDate: Date.now() },
    { billName: 'Loan', billAmount: 50, billDate: Date.now() },
    { billName: 'Transit', billAmount: 20, billDate: Date.now() },
    { billName: 'Dining Out', billAmount: 50, billDate: Date.now() },
  ];

  constructor(private renderer: Renderer2) {}

  ngOnInit(): void {}

  ngAfterViewInit() {
    this.caroItems.forEach(item => {
      this.renderer.setStyle(item.nativeElement, 'background-color', 'red')
    })
  }

}

子組件 (upcoming-card.component.html)

<div class="card">
  <div class="card__title">{{ card.billName }}</div>
  <div class="card__amount">{{ card.billAmount | currency }}</div>
  <div class="card__date">{{ card.billDate | date }}</div>
</div>

(即將到來的 card.component.ts)

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-upcoming-card',
  templateUrl: './upcoming-card.component.html',
  styleUrls: ['./upcoming-card.component.scss']
})
export class UpcomingCardComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

我已經嘗試使用@ContentChildren 訪問列表,為這種情況使用正確的模板結構以及使用正確的生命周期掛鈎,但結果相同。 我可以通過將元素 ref 和渲染器注入子級來更新 styles,但我想在父級進行。

由於對您的代碼進行了少量修改,我最終能夠訪問 ViewChildren 的 nativeElement。 我將參數{read: ElementRef}傳遞給@ViewChildren ,從那時起, item.nativeElement不再是未定義的。

請查看下面我的代碼片段或查看我在 stackblitz 上的工作示例,我在其中通過@ViewChildren 訪問了兩個導航欄並將它們塗成紅色。

  // {read: ElementRef} seems to be crucial in accessing nativeElement of a component:
  @ViewChildren('caroItem', {read: ElementRef})
  caroItems!: QueryList<ElementRef<UpcomingCardComponent>>;

  constructor(private renderer: Renderer2) {}

  ngAfterViewInit(): void {
    this.caroItems.forEach(item => {
      this.renderer.setStyle(item.nativeElement, 'background-color', 'red');
    })
  }

使用數據綁定設置樣式會容易得多:

<app-upcoming-card
      *ngFor="let card of list; let i = index"
      [style.background-color]="i < 2 ? 'red' : 'white'"
      ></app-upcoming-card>

(示例以紅色突出顯示前兩項;根據您希望完成的條件調整條件)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM