关于 angular:Angular2: 传递对象以将事件从父级绑定到子级

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

该绑定适用于标题、副标题、button.icon 和 button.name,但不适用于 button.action

parent.component.html

1
    </app-title>

parent.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
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

1
2
3
4
5
6
7
8
9
10
<section>

        {{ title }}
        <h2 *ngIf="subtitle">{{ subtitle }}

 <template *ngIf="buttons">
       
            <button *ngFor="let button of buttons" md-raised-button (click)="button.action"><md-icon *ngIf="button.icon">{{ button.icon }}</md-icon>{{ button.name }}</button>
       
    </template>

child.component.ts

1
2
3
4
5
export class ChildComponent  {

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

}


这是可以做到的:

按钮界面:

1
2
3
4
5
export interface IButton {
  Name: string;
  Icon: string;
  Action: Function
}

父组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@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() {

  }
}

子组件

1
2
3
4
5
6
7
8
9
10
11
12
@Component({
...
})
export class ChildComponent implements OnInit {
  @Input() buttons: IButton[];

  constructor() { }

  ngOnInit() {

  }
}

子 html

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

希望有帮助


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

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

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

但是,它仍然不起作用,因为 this 的上下文将在 ChildComponent 中丢失。

我要做的是在按钮声明中使用字符串文字(类似于您的代码,但没有括号,例如 'actionOne''actionTwo'...)并且每当在子项中单击按钮时,我都会向父级发出 @Output 事件:

1
2
3
4
5
6
7
8
9
10
@Component({
  template: `
    <button (click)="buttonClicked.emit(button.action)">
      {{ button.name }}
    </button>
  `
})
export class ChildComponent  {
  @Output() buttonClicked: EventEmitter<string> = new EventEmitter<string>();
}

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@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() {
      ...
  }

}