Mi problema involucra la directiva * ngif cuando una vez * ngif = true quiero que el contenido html se muestre primero antes de que mi directiva 'ModClass' pueda hacer sus cosas.

Intenté implementar ngOnInit y ngViewInit, pero no tuve suerte, ya que creo que ngOnInit se activa mientras se procesa el contenido ngif o tal vez antes cuando se genera el componente principal.

También para ngViewInit creo que necesito estar suscrito a algo, pero no sé exactamente a qué necesito suscribirme. (Podría estar completamente equivocado sobre esto, haré más investigación)

El siguiente código ilustra mi problema junto con tener un enlace stacksblitz para que no tenga que volver a crear este código en su máquina para solucionar el problema.

Lo que se supone que debe hacer el código es hacer clic en el botón para alternar una variable booleana que se usa con ngIf así: * ngIf = 'trigger'

El código ngIf mostrará un bloque div con la clase css predeterminada 'rojo' pero mi directiva lo cambiará a la clase 'azul'.

ACTUALIZACIÓN

Resulta que ngViewInit funcionaría bien siempre que use ElementRef. Gracias por toda la ayuda.

Directiva en src / app / modified-class / modified-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'))
  }
}

Contenido HTML / Hello Component encontrado en 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}
}

Linkt a Stackblitz Link

3
Alejandro Serrano 16 oct. 2018 a las 23:22

2 respuestas

La mejor respuesta

No sé si tiene la intención de usar la directiva como se describe en la pregunta (ya que la clase red parece aplicarse solo cuando el elemento no existe) pero aquí hay dos cosas que puede cambiar para hacer funciona:

  • Cambie la directiva selector de ModClass a [ModClass]
  • Inyecte ElementRef en el constructor de la directiva en lugar de HTMLElement

Aquí está el código modificado:

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');
  }
}

Consulte el stackblitz modificado.

1
ConnorsFan 16 oct. 2018 a las 20:52

Hice algunos cambios en su código:

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

Y su directiva debería ser como:

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

Para obtener más detalles sobre la directiva personalizada, acceda a este enlace: directiva Custome

También puede hacer lo mismo en ngAfterViewInit.

0
DirtyMind 16 oct. 2018 a las 20:55