繁体   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