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

问题描述 投票:0回答:5

自从我将

@Directive
创建为
SelectableDirective
以来,我对如何将 多个 值传递给自定义指令有点困惑。我已经搜索了很多,但没有在 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){}
    ....
}

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

    ...
}

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

angular typescript angular6
5个回答
162
投票

来自 文档

与组件一样,您可以添加尽可能多的指令属性绑定 您需要将它们串在模板中。

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

    ...
}

标记

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

21
投票

要传递许多选项,您可以将对象传递给 @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
}

14
投票

另一个巧妙的选择是使用

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

简单、整洁、功能强大。


4
投票

与上述解决方案类似,我在指令中使用了

@Input()
,并且能够在指令中传递多个值数组。

selector: '[selectorHere]',

@Input() options: any = {};

输入.html

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

来自 TS 文件的数组

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

0
投票

好吧,我也提出了我的答案,这可能不完整,并且在 stackoverflow 上的另一篇文章中也可以看到,我在其中提供了这个解决方案,该解决方案似乎更准确,因为参数与指令一致: (请阅读评论,这只是一个示例,而不是完整的代码),您应该可以这样使用它:

 <div *e777HasRole="['ROLE_SUPER_ADMIN']; op: 'OR'; op2 :'foo';">
    <p>foo</p>
 </div>

.

    ...
@Directive({
  selector: '[e777HasRole]',
})
//check des permissions de l'utilisateur loggé

// s'utilise comme ceci :         
//*e777HasRole="['ROLE_SUPER_ADMIN']"
//*e777HasRole="['ROLE_SUPER_ADMIN']; op: 'OR';"
//*e777HasRole="['ROLE_SUPER_ADMIN', 'ROLE_ADMIN']; op: 'AND';"
//*e777HasRole="['ROLE_SUPER_ADMIN', 'ROLE_ADMIN']; op: 'NOR';"

//ATENTION, en cours de dev sur les opérateurs, ne surtout pas utiliser tel quel !!!!
//c'est juste pour montrer le principe des paramètres sur une directive


export class E777HasRoleDirective implements OnInit {
  private loggedInUser$: Observable<User | undefined>;
  private currentLoggedInUser: User | undefined;

  private roles: string[];


  private logicalOp = 'AND';

  private isHidden = true;

  constructor(
    private element: ElementRef,
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    //private userService: UserService,
    private authenticationService: AuthenticationService,
  ) {
    this.loggedInUser$ = this.authenticationService.loggedInUser$;
    this.currentLoggedInUser = undefined;
    this.roles = [];
  }

  ngOnInit() {
    this.loggedInUser$.subscribe((user) => {
      this.currentLoggedInUser = user;
      this.updateView();
    });
  }

  @Input()
  set e777HasRole(val: string[]) {
    this.roles = val;
    this.updateView();
  }


  //THIS is the important part : notice this : "e777HasRoleOp" = "e777HasRole" (name of the directive selector) + "Op" (name of the parameter)
  @Input()
  set e777HasRoleOp(permop: string) {
    this.logicalOp = permop;
    console.log('opoerateur est : ' + permop);
    this.updateView();
  }


  //you could get a second parameter "op2" like this
  //@Input()
  //set e777HasRoleOp2(pop2: string) {
  //...
  //this.paramop2 = pop2
  //...
  //  this.updateView();
  //}
  //you should be able to use it as this
//*e777HasRole="['ROLE_SUPER_ADMIN']; op: 'OR'; op2 :'foo';"
...

  private checkPermission(): boolean {
    if (this.logicalOp.toUpperCase() === 'OR') {
      return this.checkPermission_or();
    } else if (this.logicalOp.toUpperCase() === 'AND') {
      return this.checkPermission_and();
    } else if (this.logicalOp.toUpperCase() === 'NOR') {
      return this.checkPermission_nor();
    } else {
      return false;
    }
  }

  ...
}
© www.soinside.com 2019 - 2024. All rights reserved.