¿Cómo pasar varios parámetros a las Directivas @en Angular con TypeScript?


Ya que he creado @Directive como SelectableDirective, estoy un poco confundido, acerca de cómo pasar más de un valor a la directiva personalizada. He buscado mucho pero no obtener una solución adecuada en Angular con Manuscrito.

Aquí está mi código de ejemplo:

Componente principal como MCQComponent:

import { Component, OnInit } from '@angular/core';
import { Question } from '../question/question';
import { AppService } from '../app.service/app.service';
import { SelectableDirective } from '../selectable.directive/selectable.directive';
import { ResultComponent } from '../result-component/result.component';

@Component({
    selector: 'mcq-component',
    template: "
         .....
        <div *ngIf = 'isQuestionView'>
            <ul>
                <li *ngFor = 'let opt of currentQuestion.options' 
                    [selectable] = 'opt'
                    (selectedOption) = 'onOptionSelection($event)'>
                    {{opt.option}}
                </li>
            </ul>
            .....
        </div>

    "
    providers: [AppService],
    directives: [SelectableDirective, ResultComponent]
})
export class MCQComponent implements OnInit{
    private currentIndex:any = 0;
    private currentQuestion:Question = new Question();
    private questionList:Array<Question> = [];
    ....
    constructor(private appService: AppService){}
    ....
}

Este es un componente padre que tiene una directiva personalizada [seleccionable] que toma un parámetro llamado opt.

Aquí está el código para presente directiva:

import { Directive, HostListener, ElementRef, Input, Output, EventEmitter } from '@angular/core'
import { Question } from '../question/question';

@Directive({
    selector: '[selectable]'
})
export class SelectableDirective{
    private el: HTMLElement;
    @Input('selectable') option:any;

    ...
}

Así que aquí quiero pasar más parámetros del componente padre, ¿cómo logro esto?

Author: Suren Srapyan, 2016-08-09

3 answers

De la Documentación

Al igual que con los componentes, puede agregar tantos enlaces de propiedades de directiva como es necesario encadenarlos a lo largo de la plantilla.

Agregue una propiedad de entrada a HighlightDirective llamada defaultColor:

@Input() defaultColor: string;

Marcado

<p [myHighlight]="color" defaultColor="violet">
  Highlight me too!
</p>

Angular sabe que el enlace defaultColor pertenece al HighlightDirective porque lo hiciste público con el @Input decorador.

De cualquier manera, el @Input decorador le dice a Angular que esta propiedad es público y disponible para ser enlazado por un componente padre. Sin @Input, Angular rechaza unirse a la propiedad.

Para su ejemplo

Con muchos parámetros

Agregue propiedades a la clase Directive con @Input() decorador

@Directive({
    selector: '[selectable]'
})
export class SelectableDirective{
    private el: HTMLElement;

    @Input('selectable') option:any;   
    @Input('first') f;
    @Input('second') s;

    ...
}

Y en la plantilla pase las propiedades enlazadas a su elemento li

<li *ngFor = 'let opt of currentQuestion.options' 
    [selectable] = 'opt' 
    [first]='YourParameterHere'
    [second]='YourParameterHere'
    (selectedOption) = 'onOptionSelection($event)'>
    {{opt.option}}
</li>

Aquí en el elemento li tenemos una directiva con nombre selectable. En el selectable tenemos dos @Input()'s, f con nombre first y s con nombre second. Hemos aplicado estos dos en las propiedades li con name [first] y [second]. Y nuestra directiva encontrará estas propiedades en ese elemento li, que se establecen para él con @Input() decorator. Así que selectable, [first] y [second] estará obligado a cada directiva sobre li, que tiene propiedad con estos nombres.

Con un solo parámetro

@Directive({
    selector: '[selectable]'
})
export class SelectableDirective{
    private el: HTMLElement;

    @Input('selectable') option:any;   
    @Input('params') params;

    ...
}

Marcado

<li *ngFor = 'let opt of currentQuestion.options' 
    [selectable] = 'opt' 
    [params]='{firstParam: 1, seconParam: 2, thirdParam: 3}'
    (selectedOption) = 'onOptionSelection($event)'>
    {{opt.option}}
</li>
 63
Author: Suren Srapyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-16 13:09:15

Para pasar muchas opciones puede pasar un objeto a un decorador @Input con datos personalizados en una sola línea.

En la plantilla

<li *ngFor = 'let opt of currentQuestion.options' 
                [selectable] = 'opt'
                [myOptions] ="{first: opt.val1, second: opt.val2}" // these are your multiple parameters
                (selectedOption) = 'onOptionSelection($event)' >
     {{opt.option}}
</li>

Así que en la clase directiva

@Directive({
  selector: '[selectable]'
})

export class SelectableDirective{
  private el: HTMLElement;
  @Input('selectable') option:any;
  @Input('myOptions') data;

  //do something with data.first
  ...
  // do something with data.second
}
 8
Author: Dag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-20 19:30:07

Otra buena opción es usar el Directive como un elemento y no como un atributo.

@Directive({
   selector: 'app-directive'
})
export class InformativeDirective implements AfterViewInit {

    @Input()
    public first: string;

    @Input()
    public second: string;

    ngAfterViewInit(): void {
       console.log(`Values: ${this.first}, ${this.second}`);
    }
}

Y esta directiva se puede usar así:

<app-someKindOfComponent>
    <app-directive [first]="'first 1'" [second]="'second 1'">A</app-directive>
    <app-directive [first]="'First 2'" [second]="'second 2'">B</app-directive>
    <app-directive [first]="'First 3'" [second]="'second 3'">C</app-directive>
</app-someKindOfComponent>`

Simple, limpio y poderoso.

 1
Author: Aharon Ohayon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-29 10:22:32