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

时间:2018-10-16 20:22:41

标签: angular angular-directive lifecycle angular-ng-if ngif

我的问题涉及* ngif指令,当一次* ngif = true时,我希望先显示html内容,然后再执行'ModClass'指令。

我尝试实现ngOnInit和ngViewInit,但是没有运气,因为我相信ngOnInit在渲染ngif内容时触发,或者在生成父组件时更早触发。

对于ngViewInit,我想我也需要订阅某些东西,但我不知道到底需要订阅什么。 (对此我可能完全错了,它将进行更多研究)

以下代码说明了我的问题以及拥有stacksblitz链接的情况,因此您无需在计算机上重新创建此代码即可进行故障排除。

假定代码要做的是在按钮上单击,从而切换与ngIf一起使用的布尔变量: * ngIf ='trigger'

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

更新

结果证明,只要我使用ElementRef,ngViewInit都可以正常工作。 感谢您的所有帮助。

src / app / modify-class / 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.component中找到

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 个答案:

答案 0 :(得分:1)

我不知道您是否打算使用问题中所述的指令(因为[{'OFFER_USED_CONDITION': ['\n Used\n \n\n\n\n-\n', '\n Acceptable\n', '\n', '\n Used\n \n\n\n\n-\n', '\n Good\n', '\n', '\n Used\n \n\n\n\n-\n', '\n Good\n', '\n', '\n Used\n \n\n\n\n-\n', '\n Good\n', '\n', '\n Collectible\n \n\n\n\n-\n', '\n Acceptable\n', '\n', '\n Used\n \n\n\n\n-\n', '\n Very Good\n', '\n', '\n Used\n \n\n\n\n-\n', '\n Good\n', '\n', '\n Used\n \n\n\n\n-\n', '\n Very Good\n', '\n', '\n Used\n \n\n\n\n-\n', '\n Like New\n', '\n', '\n Used\n \n\n\n\n-\n', '\n Very Good\n', '\n']}] 类似乎仅在元素不存在时才适用),但是您可以做两件事进行更改以使其起作用:

  • 将指令selectorred更改为ModClass
  • 在指令构造函数中注入[ModClass]而不是ElementRef

这是修改后的代码:

HTMLElement

请参见the modified stackblitz

答案 1 :(得分:0)

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

<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";
  }
}

有关自定义指令的更多详细信息,请通过以下链接:Custome directive

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