如何使用TypeScript将多个参数传递给Angular中的@Directives?

Shr*_*ree 54 javascript typescript angular angular6

因为我创建了@Directiveas SelectableDirective,我有点困惑,关于如何将多个值传递给custom指令.我已经搜索了很多,但没有得到适当的解决方案在AngularTypescript.

这是我的示例代码:

父组件为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){}
    ....
}
Run Code Online (Sandbox Code Playgroud)

这是一个具有自定义指令[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;

    ...
}
Run Code Online (Sandbox Code Playgroud)

所以在这里我想从父组件传递更多参数,我该如何实现呢?

Sur*_*yan 98

来自文档

与组件一样,您可以通过在模板中将它们串起来添加任意数量的指令属性绑定.

添加一个输入属性到HighlightDirective被调用defaultColor:

@Input() defaultColor: string;
Run Code Online (Sandbox Code Playgroud)

标记

<p [myHighlight]="color" defaultColor="violet">
  Highlight me too!
</p>
Run Code Online (Sandbox Code Playgroud)

Angular知道defaultColor绑定属于the,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;

    ...
}
Run Code Online (Sandbox Code Playgroud)

并在模板中将绑定属性传递给li元素

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

li元素上,我们有一个带有名称的指令selectable.在selectable我们有两个@Input(),f名字firsts名字second.我们已经在li名称[first]和属性上应用了这两个[second].我们的指令将在该li元素上找到这些属性,这些属性是使用@Input()装饰器为他设置的.所以selectable,[first]并将[second]绑定到每个指令li,其中包含具有这些名称的属性.

带单参数

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

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

标记

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

  • @ChrisTarasovs当你使用`[defaultColor] ="violet"`时,它试图执行正确的部分并找到一个名为violet的属性,没有`[]`括号它将右边的部分用作字符串 (3认同)

Dag*_*Dag 13

要传递许多选项,您可以将对象传递给@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>
Run Code Online (Sandbox Code Playgroud)

所以在指令课上

@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
}
Run Code Online (Sandbox Code Playgroud)

  • @MartinJH值得一提的是,使用变更检测策略`OnPush`时,此解决方案效果不佳.如果要使用该策略,最好避免将对象用作@Input(). (3认同)

Aha*_*yon 9

另一个巧妙的选择是将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}`);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个指令可以这样使用:

<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>`
Run Code Online (Sandbox Code Playgroud)

简单、整洁、强大。