it-roy-ru.com

Как передать несколько параметров в @Directives в Angular с TypeScript?

Поскольку я создал @Directive как SelectableDirective, я немного запутался в том, как передать более одного значения в пользовательскую директиву. Я много искал, но не нашел правильного решения в Angular с TypeScript.

Вот мой пример кода: 

Родительский компонент как 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){}
    ....
}

Это родительский компонент, имеющий пользовательскую директиву [selectable] , которая принимает один параметр с именем opt

Вот код для этой директивы: 

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;

    ...
}

Итак, здесь я хочу передать больше параметров из родительского компонента, как мне этого добиться?

45
Shree

Из Документация

Как и в случае с компонентами, вы можете добавить столько привязок свойств директивы, сколько вам нужно, цепляя их вместе в шаблоне. 

Добавьте свойство ввода в HighlightDirective с именем defaultColor:

@Input() defaultColor: string;

Markup

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

Angular знает, что привязка defaultColor принадлежит HighlightDirective, потому что вы сделали ее общедоступной с помощью @Input декоратор.

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

Для вашего примера

Со многими параметрами

Добавьте свойства в класс Directive с декоратором @Input()

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

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

    ...
}

И в шаблоне передайте связанные свойства вашему элементу li

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

Здесь, в элементе li, у нас есть директива с именем selectable. В selectable у нас есть две @Input(), f с именем first и s с именем second. Мы применили эти два к свойствам li с именами [first] и [second]. И наша директива найдет эти свойства для того элемента li, которые установлены для него с помощью @Input() decorator. Таким образом, selectable, [first] и [second] будут связаны с каждой директивой li, которая имеет свойство с этими именами.

С одним параметром

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

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

    ...
}

Markup

<li *ngFor = 'let opt of currentQuestion.options' 
    [selectable] = 'opt' 
    [params]='{firstParam: 1, seconParam: 2, thirdParam: 3}'
    (selectedOption) = 'onOptionSelection($event)'>
    {{opt.option}}
</li>
73
Suren Srapyan

чтобы передать много опций, вы можете передать объект в декоратор @Input с пользовательскими данными в одной строке.

В шаблоне

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

так в классе Директивы

@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
}
9
Dag

Еще одна полезная опция - использовать Directive как элемент, а не как атрибут.

@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}`);
    }
}

И эту директиву можно использовать так:

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

Просто, аккуратно и мощно.

2
Aharon Ohayon

Подобно вышеупомянутым решениям, я использовал @Input() в директиве и мог передавать несколько массивов значений в директиве.

selector: '[selectorHere]',

@Input() options: any = {};

Input.html

<input selectorHere [options]="selectorArray" />

Массив из файла TS 

selectorArray= {
  align: 'left',
  prefix: '$',
  thousands: ',',
  decimal: '.',
  precision: 2
};
0
Deepak