Как вызвать директиву внутри ngIf, когда ngIf заканчивает рендеринг html-элементов? - PullRequest
0 голосов
/ 16 октября 2018

Моя проблема связана с директивой * ngif, когда однажды * ngif = true, я хочу, чтобы содержимое html отображалось первым, прежде чем моя директива ModClass сможет выполнить свои задачи.

Я пытался реализовать ngOnInit и ngViewInit, но нетудачи, поскольку я верю, что ngOnInit срабатывает во время рендеринга содержимого ngif или, возможно, раньше, когда генерируется родительский компонент.

Также для ngViewInit я думаю, что мне нужно подписаться на что-то, но я не знаю точно, на что мне нужно подписаться.(Я могу быть совершенно неправ в этом, и мы проведем дополнительные исследования)

Следующий код иллюстрирует мою проблему наряду с наличием ссылки на стек, поэтому вам не придется заново создавать этот код на своем компьютере для устранения неполадок.

То, что код должен делать, это нажатие кнопки, переключение логической переменной, используемой с ngIf, следующим образом: * ngIf = 'trigger'

Код ngIf будетотобразить блок div с классом css по умолчанию 'red', но моя директива изменит его на класс 'blue'.

UPDATE

Оказывается, ngViewInit будет работать нормально, какПока я использую ElementRef.Спасибо за помощь.

Директива в 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'))
  }
}

HTML / Hello Содержимое компонента находится в src / app / hello.component

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

ссылка на Связь со стеком

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Я внес некоторые изменения в ваш код:

<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.

0 голосов
/ 16 октября 2018

Я не знаю, намереваетесь ли вы использовать директиву, как описано в вопросе (поскольку класс 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');
  }
}

См. модифицированный стек * блиц .

...