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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38843532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 21:55:58  来源:igfitidea点击:

How to pass multiple parameter to @Directives (@Components) in Angular with TypeScript?

javascriptangulartypescriptangular6

提问by Shree

Since I've created @Directiveas SelectableDirective, I'm little bit confused, about how to pass more than onevalue to the custom directive. I have searched a lot but didn't get proper solution in Angularwith Typescript.

由于我创建了@Directiveas SelectableDirective,我对如何将多个值传递给自定义指令有点困惑。我已经搜索了很多,但没有在Angular 中使用Typescript得到正确的解决方案。

Here is what my sample code is:

这是我的示例代码:

Parent Component as MCQComponent:

父组件为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){}
    ....
}

This is a parent component having custom directive [selectable]which takes one param called opt.

这是一个具有自定义指令[selectable]的父组件,它采用一个名为opt 的参数。

Here is the code for this directive:

这是该指令的代码:

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;

    ...
}

So here I want to pass more parameters from parentcomponent, how do I achieve this?

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

回答by Suren Srapyan

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 HighlightDirectivecalled defaultColor:

@Input() defaultColor: string;

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

HighlightDirective调用添加输入属性defaultColor

@Input() defaultColor: string;

Markup

标记

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

Angularknows that the defaultColorbinding belongs to the HighlightDirectivebecause you made it public with the @Inputdecorator.

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

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

Angular知道defaultColor绑定属于 ,HighlightDirective因为您使用@Input装饰器将其公开。

无论哪种方式,@Input装饰器都会告诉 Angular 这个属性是公共的,并且可以被父组件绑定。没有 @Input,Angular 拒绝绑定到该属性。

For your example

对于你的例子

With many parameters

有很多参数

Add properties into the Directiveclass with @Input()decorator

Directive使用@Input()装饰器将属性添加到类中

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

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

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

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

li元素上,我们有一个名为 name 的指令selectable。在selectable我们有两个@Input()fwith namefirstswith name second。我们已将这两个应用li到名称为[first]和的属性上[second]。我们的指令会在那个li元素上找到这些属性,这些属性是用@Input()装饰器为他设置的。所以selectable, [first]and[second]将绑定到 上的每个指令li,它具有这些名称的属性。

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>

回答by Dag

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

要传递许多选项,您可以在一行中将对象传递给带有自定义数据的 @Input 装饰器。

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
}

回答by Aharon Ohayon

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

另一个巧妙的选择是将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}`);
    }
}

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.

简单、整洁、强大。

回答by Deepak

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

类似于我@Input()在指令中使用的上述解决方案,并且能够在指令中传递多个值数组。

selector: '[selectorHere]',

@Input() options: any = {};

Input.html

输入.html

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

Array from TS file

来自 TS 文件的数组

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