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


75

由于我已经创建@Directive为as SelectableDirective,因此对于如何将多个值传递给自定义指令我有些困惑。我已经搜索了很多,但是没有用TypescriptAngular中得到正确的解决方案。

这是我的示例代码:

父组件为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;

    ...
}

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

Answers:


127

文档中

与组件一样,您可以通过在模板中添加它们来添加所需数量的指令属性绑定。

输入属性添加到HighlightDirective名为defaultColor

@Input() defaultColor: string;

标记

<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元素上,我们有一个名为name的指令selectable。在中,selectable我们有两个@Input(),分别f是namefirstsname 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;

    ...
}

标记

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

但是我应该在父组件中写些什么?
Shree

@Shree看到编辑的答案。在li您中,您以相同的方式传递参数
Suren Srapyan

但是,如果我有多个attr指令怎么办?
Shree

您将使用@Input装饰器提供其参数
Suren Srapyan '16

4
@ChrisTarasovs在使用时[defaultColor]="violet",会尝试执行正确的部分并找到名称为violet的属性,不带[]括号,它将正确的部分用作字符串
Suren Srapyan

18

要传递许多选项,可以将对象与一行中的自定义数据传递给@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
}

这就是我想要的。这样一来,我只能使用一个指令绑定pr。html元素。谢谢一堆@Dag!
MartinJH '17

3
@MartinJH值得一提的是,使用更改检测策略时,此解决方案不能很好地工作OnPush。如果要使用该策略,最好避免将对象用作@Input()。
enf0rcer

@ enf0rcer当然,您仍然可以在OnPush上使用此方法,只需要将一个新对象推送到指令即可。因此,将对象文字嵌入模板是不可行的-您需要通过组件上的可观察对象来推动它。
美眉

8

另一个简洁的选择是将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>`

简单,整洁且功能强大。


谢谢,这也是最简单的方法。
Shree

我没有意识到指令可以用作元素。太棒了
美眉

1

与以上@Input()在指令中使用的解决方案相似,该指令能够传递多个值数组。

selector: '[selectorHere]',

@Input() options: any = {};

Input.html

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

TS文件中的数组

selectorArray= {
  align: 'left',
  prefix: '$',
  thousands: ',',
  decimal: '.',
  precision: 2
};
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.