Angular2:传递 object 以将事件从 parent 绑定到 child

Angular2: Passing an object to bind event from parent to child

标题、副标题、button.icon 和 button.name 的绑定工作正常,但不适用于 button.action

parent.component.html

    <app-title [title]="title" [subtitle]="subtitle" [buttons]="buttons"></app-title>

parent.component.ts

export class ParentComponent {

actionOne() {
    ...
}

title = 'Title';
subtitle = 'Subtitle';
buttons = [
    { 'name': 'Name1', 'icon': 'Icon1', 'action': 'actionOne()'},
    { 'name': 'Name2', 'icon': 'Icon2', 'action': 'actionTwo()'},
    { 'name': 'Name3', 'icon': 'Icon3', 'action': 'actionThree()'}
];

}

child.component.html

<section>
<div class="text-wrapper">
        <h1>{{ title }}</h1>
        <h2 *ngIf="subtitle">{{ subtitle }}</h2>
</div>
 <template *ngIf="buttons">
        <div class="buttons-wrapper">
            <button *ngFor="let button of buttons" md-raised-button (click)="button.action"><md-icon *ngIf="button.icon">{{ button.icon }}</md-icon>{{ button.name }}</button>
        </div>
    </template>
</div>

child.component.ts

export class ChildComponent  {

@Input() title:string;
@Input() subtitle:string;
@Input() buttons:string;

}

您的代码无法运行,因为您将字符串文字而非方法引用传递给 child。例如,在 button.action 属性 中,您的 ChildComponent 看到的是字符串文字 "actionOne()",而不是方法 actionOne().

为了在声明按钮时传递方法引用,您必须删除方法名称周围的引号和 parentheses 并在它们前面加上前缀 this.:

buttons = [
    { 'name': 'Name1', 'icon': 'Icon1', 'action': this.actionOne },
    { 'name': 'Name2', 'icon': 'Icon2', 'action': this.actionTwo },
    { 'name': 'Name3', 'icon': 'Icon3', 'action': this.actionThree }
]

但是,它仍然无法工作,因为 this 的上下文将在 ChildComponent.

中丢失

我会做的是在按钮声明中使用字符串文字(类似于您的代码,但没有 parentheses,例如 'actionOne''actionTwo'...)和每当在 child 中单击按钮时,我都会向 parent:

发出一个 @Output 事件
@Component({
  template: `
    <button (click)="buttonClicked.emit(button.action)">
      {{ button.name }}
    </button>
  `
})
export class ChildComponent  {
  @Output() buttonClicked: EventEmitter<string> = new EventEmitter<string>();
}

请注意,我在发出事件时传递了 button.action 属性(字符串)。

现在,ParentComponent 可以侦听该事件并使用接收到的字符串作为标识符来决定调用哪个本地方法:

@Component({
  template: `
    <child-comp (buttonClicked)="handleAction($event)"></child-comp>
  `
})
export class ParentComponent  {

  handleAction(actionName) {
    // Here, put some logic to call a local method based on `actionName`
    // Something like this[actionName]();
  }

  actionOne() {
      ...
  }

  actionTwo() {
      ...
  }

}

这是可以做到的:

按钮界面:

export interface IButton {
  Name: string;
  Icon: string;
  Action: Function
}

Parent 分量:

@Component({
...
})
export class ParentComponent implements OnInit {
  buttons: IButton[] = [
    {
      Name: 'Hello',
      Icon: 'Test',
      Action: this.actionOne.bind(this) // we need to make sure this is scoped correctly
    }
  ];

  actionOne(){
    console.log('This is from action One');
  }

  constructor() { }

  ngOnInit() {

  }
}

Child 分量

@Component({
...
})
export class ChildComponent implements OnInit {
  @Input() buttons: IButton[];

  constructor() { }

  ngOnInit() {

  }
}

Child html

<div *ngIf="buttons">
  <button *ngFor="let button of buttons" (click)="button.Action()">{{button.Name}}</button>
</div>

希望对您有所帮助