简体   繁体   English

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

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

I'm trying to create a carousel component that has n amount of child components based on whatever size list it will get.我正在尝试创建一个轮播组件,该组件根据它将获得的任何大小列表具有 n 个子组件。 I want the parent (carousel) to control the styling for children as it manipulates the size of the list and track the indexes to rotate items around the carousel and style accordingly.我希望父项(旋转木马)控制子项的样式,因为它操纵列表的大小并跟踪索引以围绕旋转木马旋转项目并相应地设置样式。 There will buttons to control this behaviour.将有按钮来控制此行为。 旋转木马的例子

I'm trying to apply styles and get the functionality working but cannot seem to access the styles by getting a query list of element refs using view children and template refs (I also tried with content children initially, with the template set up properly).我正在尝试应用 styles 并使功能正常工作,但似乎无法通过使用视图子项和模板引用获取元素引用的查询列表来访问 styles(我最初也尝试使用内容子项,模板设置正确)。 I can change them if I inject the element ref and renderer at the child level, but I don't want to do this here.如果我在子级别注入元素引用和渲染器,我可以更改它们,但我不想在这里这样做。 I get the error: TypeError: Cannot read properties of undefined (reading 'style') But not when I do the exact same thing doing it from the child level.我收到错误: TypeError: Cannot read properties of undefined (reading 'style')但是当我从子级别做完全相同的事情时却没有。

Am I going about this incorrectly?我做错了吗? How do I change children styles in a list from @ViewChildren() from a parent?如何从父母的 @ViewChildren() 更改列表中的孩子 styles?

Parent component (carousel.component.html)父组件(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>

(carousel.component.ts) (旋转木马.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')
    })
  }

}

Child component (upcoming-card.component.html)子组件 (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>

(upcoming-card.component.ts) (即将到来的 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 {
  }

}

I've tried accessing the list using @ContentChildren, having the template structure properly for this case as well as using the proper lifecycle hook, but it results in the same.我已经尝试使用@ContentChildren 访问列表,为这种情况使用正确的模板结构以及使用正确的生命周期挂钩,但结果相同。 I can update styles by injecting the element ref and renderer into the child, but I want to do it at the parent level.我可以通过将元素 ref 和渲染器注入子级来更新 styles,但我想在父级进行。

Thanks to a small modification of your code, I was eventually able to access the nativeElement of the ViewChildren.由于对您的代码进行了少量修改,我最终能够访问 ViewChildren 的 nativeElement。 I passed the argument {read: ElementRef} to @ViewChildren and from then on item.nativeElement was no longer undefined.我将参数{read: ElementRef}传递给@ViewChildren ,从那时起, item.nativeElement不再是未定义的。

Please see my code-snippet below or check out my working example on stackblitz where I accessed two nav-bars via @ViewChildren and colored them red.请查看下面我的代码片段或查看我在 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');
    })
  }

It would be vastly easier to set the style using data binding:使用数据绑定设置样式会容易得多:

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

(example highlights the first two items in red; adjust the conditions to whatever you wish to accomplish) (示例以红色突出显示前两项;根据您希望完成的条件调整条件)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 angular 更新到 v14 后,TSlint 规则变为 ESlint - TSlint rules to ESlint after update angular to v14 v14 中 Angular 编译器的替代品是什么? - What is the replacement for the Angular Compiler in v14? Angular 6 在 AngularElements 中使用 ContentChildren/ViewChildren - CustomComponents - Angular 6 using ContentChildren/ViewChildren in AngularElements - CustomComponents Angular Material v15 主题如何从 v14 工作 - How dose Angular Material v15 theming work coming from v14 Angular 从 v12 迁移到 v14 - Angular migration from v12 to v14 如何在ES5中访问Component的ViewChildren和ContentChildren? - How to access ViewChildren and ContentChildren of Component in ES5? 如何在 angular v14 中的纯 function 中使用 class 外部注入? - How to use inject outside class in pure function in angular v14? Safari 中带有 Angular (v14) 应用程序的空白页面 - Blank page with Angular (v14) app in Safari angular 9 使用查询列表(contentChildren 或 ViewChildren)对同级 dom 重新排序/排序 - angular 9 reorder/sort siblings dom by using querylist(contentChildren or ViewChildren) 找不到模块“@angular/cdk/dialog”- Angular 将 v13 升级到 v14 问题 - Cannot find module '@angular/cdk/dialog' - Angular upgrade v13 to v14 issue
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM