当前位置: 首页 > 知识库问答 >
问题:

一旦ngIf完成呈现html元素,如何在ngIf中触发指令?

吴单鹗
2023-03-14

我的问题涉及到*ngif指令,一旦*ngif=true我希望在我的'ModClass'指令可以做它的东西之前先渲染html内容。

我试图实现ngOnInit和ngViewInit,但没有运气,因为我相信ngOnInit触发器,而ngif内容正在渲染或可能更早时,父组件生成。

同样对于ngViewInit,我想我需要订阅一些东西,但我不知道我需要订阅什么。(我可能完全错了,我会做更多的研究)

下面的代码说明了我的问题以及stacksblitz链接,这样您就不必在计算机上重新创建此代码来进行故障排除。

代码要做的是点击按钮,切换一个与ngIf一起使用的布尔变量:*ngIf='trigger'

ngIf代码将显示一个带有默认css类“red”的div块,但我的指令将其更改为“blue”类。

更新

事实证明,只要我使用ElementRef,ngViewInit就可以正常工作。谢谢你的帮助。

指令在src/app/修改类/modify-class.directive

import { Directive, OnInit } from '@angular/core'

@Directive({
  selector: 'ModClass'
})
export class ModifyClassDirective implements OnInit {

  constructor (private htmlElement: HTMLElement) {}

  //should i try ngViewinit instead
  ngOnInit () {
    this.activateThisClass()
  }

  /*ngViewInit () {
    this.activateThisClass()
  }*/
  //this function should execute once ng-if condition is true and html is rendered
  activateThisClass () {
    console.log('i\'ve been triggered')
    const list = this.htmlElement.getElementsByClassName('red')
    list.forEach(element => element.classList.remove('red'))
    list.forEach(element => element.classList.add('blue'))
  }
}

在src/app/Hello中找到HTML/Hello组件内容。组成部分

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

@Component({
  selector: 'hello',
  template: `
<h1>Hello {{name}}!</h1>
  <button ModClass='' (click)="trigger=!trigger;"> click me </button>

<div *ngIf='trigger'> 

  <!-- This is what i want to change once it is rendered -->
  <div ModClass='' class='red'> this will/should be overwritten and turn blue </div>

</div>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {
  @Input() name: string;
  @Input() trigger: boolean;

  constructor() {this.trigger = false}
}

链接到Stackblitz Link

共有2个答案

云慈
2023-03-14

我对您的代码做了一些更改:

<button (click)="trigger=!trigger;"> click me </button>

<div *ngIf='trigger'> 
  <!-- This is what i want to change once it is rendered -->
  <div ModClass class='red'> this will/should be overwritten and turn blue </div>

你的指令应该是:

import { Directive, OnInit } from '@angular/core'
import { ElementRef } from '@angular/core';
@Directive({
  selector: '[ModClass]' // changed
})
export class ModifyClassDirective implements OnInit {
  constructor (private el: ElementRef) {}
  ngOnInit () {
    this.activateThisClass()
  }
  activateThisClass () {
    this.el.nativeElement.style.backgroundColor = "blue";
  }
}

有关自定义指令的更多详细信息,请访问此链接:自定义指令

您也可以在ngAfterViewInit中执行同样的操作。

汪建白
2023-03-14

我不知道您是否打算使用问题中描述的指令(因为red类似乎仅在元素不存在时才应用),但有两件事可以更改以使其工作:

  • 将指令选择器从ModClass更改为[ModClass]
  • 在指令构造函数中插入ElementRef,而不是HTMLElement

以下是修改后的代码:

import { Directive, ElementRef, OnInit } from '@angular/core'

@Directive({
  selector: '[ModClass]'
})
export class ModifyClassDirective implements OnInit {

  constructor (private elementRef: ElementRef) {}

  ngOnInit () {
    this.activateThisClass()
  }

  activateThisClass () {
    console.log("activateThisClass triggered!")
    const element = this.elementRef.nativeElement;
    element.classList.remove('red');
    element.classList.add('blue');
  }
}

参见修改后的stackblitz。

 类似资料:
  • 我在从API检索页面上显示的数据时遇到问题。 API 正在返回对象数组,所以我有多个 *ngIf 以便知道要显示的 html div。重要的是要说API不是每次都返回所有对象,这取决于数据。 问题是,在第一次调用 API 后,html 被正确呈现,所有内容都按预期显示。在第二次调用时(输入参数现在当然不同了),API 返回不同的数据(更多对象),但 HTML 是相同的,所以我在页面上缺少几个 di

  • 在我的 Angular 5 应用程序中,我正在循环创建 元素: 但是我只想在满足某些条件的情况下显示该行。我知道我不能一起使用和,但我不知道如何绕过这个问题。 我看到一篇文章说使用构造在tr中添加一个模板,但这似乎不再是有效的语法。如果我这样尝试: 然后我得到运行时错误。 应用组件。html:14错误错误:StaticInjectorError(AppModule)[NgIf-

  • 当我在同一个元素上使用和时,我遇到了一个问题。 我知道简单的解决方案是在新元素上移动。例如: 但是当我使用这个解决方案时,我不能使用变量。并且这个解决方案隐藏了

  • 这两个语法都是完全有效的,对于语法1,您可以像这里描述的那样更进一步,但是对于使用其中一个和另一个有什么性能/最佳实践建议吗?

  • 我有一个问题,试图在同一个元素上使用Angular的和。 当尝试在中循环遍历集合时,该集合被视为,因此在尝试访问模板中的属性时失败。 我知道简单的解决方案是将向上移动一个级别,但是对于像在中循环列表项这样的场景,如果集合是空的,我会得到一个空的,或者我的被包装在冗余容器元素中。 示例在这个plnkr。 注意控制台错误: 我做错什么了还是这是一个错误?