【问题标题】:Creating a reusable button component in Angular在 Angular 中创建可重用的按钮组件
【发布时间】:2018-09-24 08:24:57
【问题描述】:

我正在尝试在 Angular 5 中创建一个组件,该组件将容纳一个可重用的按钮模板。在我的应用程序的不同部分,按钮会调用不同的函数,所以我希望能够告诉给定的按钮实例要调用什么函数。我知道我可以在任何需要的地方为按钮创建一个 HTML 标记,但我希望我可以创建一个可重用的组件,这样我就可以确保整个应用程序的格式一致。

错误

 Got interpolation ({{}}) where expression was expected at column 0 in 
        [{{functioncall}}]

组件

<div id = "button">
  <button type="button" class= "btn" (click) ="{{functioncall}}" >{{label}}</button>
</div>

HTML

 import { Component, OnInit, Input } from '@angular/core';

    @Component({
      selector: 'app-button',
      templateUrl: './button.component.html',
      styleUrls: ['./button.component.css']
    })
    export class ButtonComponent implements OnInit {
      @Input() label:string;
      @Input() functionCall:string;

      constructor() { }

      ngOnInit() {
      }
    }

【问题讨论】:

    标签: angular button


    【解决方案1】:

    你必须使用 @Output 装饰器来发出一些事件(从子到父)

    button.component.ts:

    @Input() label: string;
    @Output() onClick = new EventEmitter<any>();
    
    onClickButton(event) {
        this.onClick.emit(event);
      }
    

    button.component.html:

    <div id = "button">
      <button type="button" class= "btn" (click)="onClickbutton($event)" >{{label}}</button>
    </div>
    

    parent.component.ts

    label = "button label"
    
      functioncall(event) {
        console.log('functioncall', event);
      }
    

    parent.component.html

    <app-button (onClick)="functioncall($event)" [label]="label"></app-button>
    

    查看示例:https://stackblitz.com/edit/angular-gghsax

    【讨论】:

    • 我用新的 StackBlitz 链接刷新了应用程序,因为您的链接不再有效 (stackblitz.com/edit/angular-gghsax)。此外,我认为您缺少@Input() label: string; 作为button.component.ts 中的变量声明(至少引发了该错误)-可能是兼容性问题(现在是Angular 7)。但是,很棒的工作!
    • 可以说我想要按钮中的图标(谷歌图标,如购物车)。如何动态添加?
    • 您可以使用角度内容投影来做到这一点。看这个例子stackblitz.com/edit/…
    • 应该避免在组件中使用像id = "button" 这样的硬编码ID。组件是可重用的,并且 ID 必须是唯一的。否则标记一致性会受到影响。还有一点:我不认为将每个按钮包装在一个 div 中是直截了当的。
    【解决方案2】:

    除了@miladfm 答案,我建议在此处使用&lt;ng-content&gt;&lt;/ng-content&gt; 指令来传递内容而不是拉入{{label}},将@Output 装饰器分配给click 而不是onClick,以及使用MouseEvent 类型而不是any。使用这些更改将允许按钮组件在使用时在语法上更像原生按钮:

    button.component.ts

    ...
    @Output() click = new EventEmitter<MouseEvent>();
    
    onClickButton(event) {
      this.onClick.emit(event);
    }
    ...
    

    button.component.html

    <div id = "button">
      <button type="button" class="btn" (click)="onClickbutton($event)">
        <ng-content></ng-content>
      </button>
    </div>
    

    parent.component.ts

    ...
    functioncall(e: MouseEvent) {
     // do stuff
    }
    ...
    

    parent.component.html

    <app-button  (click)="functioncall($event)">Your Label Here</app-button>
    

    【讨论】:

    • 好像有一个名为click的事件会触发两次点击事件,所以我会坚持onClick这个名字。
    • 或者,您可以使用event.stopPropagation(),如下所述:stackoverflow.com/a/42112272/612847
    【解决方案3】:

    可重用组件 - 它对我有用

    我已将按钮创建为可重用组件

    • button.component.html

      {{label}} button >

    • button.component.ts

      export class ButtonComponent {
      
            @Input() label: string;
      
            @Output() onClick = new EventEmitter<any>();
      
            constructor() {}
      
            onClickButton(event) {
      
                this.onClick.emit(event);
      
            }
       }
      
    • user.component.html

    • user.component.ts

      label = 'Hello World';

    【讨论】:

      猜你喜欢
      • 2023-03-09
      • 2016-12-24
      • 1970-01-01
      • 2022-06-12
      • 2017-11-14
      • 2016-08-15
      • 2021-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多