如何使用 TypeScript 以角度传递多个参数给@Directive (@组件) ?

因为我已经将 @Directive创建为 SelectableDirective,所以对于如何将 不止一个值传递给自定义指令,我有点困惑。我已经找了很多,但没有得到适当的解决方案在 角度打印稿

下面是我的示例代码:

作为 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){}
....
}

这是一个具有自定义指令 [可选]的父组件,该指令接受一个名为 选吧的参数。

下面是这个指令的代码:

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;


...
}

所以这里我想传递 来自父级的更多参数组件,我如何实现这一点?

152854 次浏览

From the Documentation

As with components, you can add as many directive property bindings as you need by stringing them along in the template.

Add an input property to HighlightDirective called defaultColor:

@Input() defaultColor: string;

Markup

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

Angular knows that the defaultColor binding belongs to the HighlightDirective because you made it public with the @Input decorator.

Either way, the @Input decorator tells Angular that this property is public and available for binding by a parent component. Without @Input, Angular refuses to bind to the property.

For your example

With many parameters

Add properties into the Directive class with @Input() decorator

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


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


...
}

And in the template pass bound properties to your li element

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

Here on the li element we have a directive with name selectable. In the selectable we have two @Input()'s, f with name first and s with name second. We have applied these two on the li properties with name [first] and selectable0. And our directive will find these properties on that li element, which are set for him with @Input() decorator. So selectable, [first] and selectable0 will be bound to every directive on li, which has property with these names.

With single parameter

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

to pass many options you can pass a object to a @Input decorator with custom data in a single line.

In the template

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

so in Directive class

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

Another neat option is to use the Directive as an element and not as an attribute.

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

And this directive can be used like that:

<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, neat and powerful.

Similar to the above solutions I used @Input() in a directive and able to pass multiple arrays of values in the directive.

selector: '[selectorHere]',


@Input() options: any = {};

Input.html

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

Array from TS file

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