如何使用 TypeScript 将多个参数传递给 Angular 中的 @Directives (@Components)?
Posted
技术标签:
【中文标题】如何使用 TypeScript 将多个参数传递给 Angular 中的 @Directives (@Components)?【英文标题】:How to pass multiple parameter to @Directives (@Components) in Angular with TypeScript? 【发布时间】:2016-12-15 01:47:01 【问题描述】:由于我将@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;
...
所以这里我想从父组件传递更多参数,我该如何实现呢?
【问题讨论】:
【参考方案1】:与上述解决方案类似,我在指令中使用了@Input()
,并且能够在指令中传递多个值数组。
selector: '[selectorHere]',
@Input() options: any = ;
输入.html
<input selectorHere [options]="selectorArray" />
TS 文件中的数组
selectorArray=
align: 'left',
prefix: '$',
thousands: ',',
decimal: '.',
precision: 2
;
【讨论】:
【参考方案2】:另一个巧妙的选择是将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>`
简单、整洁且功能强大。
【讨论】:
谢谢,这也是最简单的方法。 我没有意识到指令可以用作元素。太棒了。【参考方案3】:来自Documentation
与组件一样,您可以添加尽可能多的指令属性绑定 您需要通过在模板中将它们串起来。
向
HighlightDirective
添加一个名为defaultColor
的输入属性:@Input() defaultColor: string;
标记
<p [myHighlight]="color" defaultColor="violet"> Highlight me too! </p>
Angular 知道
defaultColor
绑定属于HighlightDirective
,因为您使用@Input
将其公开 装饰器。不管怎样,
@Input
装饰器告诉 Angular 这个属性是 public 并且可用于由父组件绑定。没有@Input
,Angular 拒绝绑定到该属性。
举个例子
有很多参数
使用 @Input()
装饰器将属性添加到 Directive
类中
@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
。我们已将这两个应用到名称为[first]
和[second]
的li
属性上。我们的指令将在 li
元素上找到这些属性,这些属性是使用 @Input()
装饰器为他设置的。所以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 查看编辑后的答案。在li
中你以同样的方式传递一个参数
但是如果我有多个 attr 指令呢?
您将使用@Input 装饰器给出它所对应的参数
@ChrisTarasovs 当你使用[defaultColor]="violet"
时,它会尝试执行正确的部分并找到一个名为紫罗兰色的属性,没有[]
括号它使用正确的部分作为字符串【参考方案4】:
要传递许多选项,您可以将对象传递给 @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 值得一提的是,该解决方案在使用更改检测策略OnPush
时效果不佳。如果您想使用该策略,最好避免将对象用作@Input()。
@enf0rcer 当然你仍然可以在 OnPush 中使用这个方法,你只需要将一个新对象推送到指令中。所以,在模板中嵌入对象字面量是不行的——你需要通过组件上的一个 observable 来推动它。以上是关于如何使用 TypeScript 将多个参数传递给 Angular 中的 @Directives (@Components)?的主要内容,如果未能解决你的问题,请参考以下文章