在 Angular 2+ 中,我可以检测指令(如 routerLink)何时应用于我的自定义组件吗?

pan*_*a82 1 javascript angular

我有一个自定义按钮组件,如下所示(简化):

@Component({
    selector: 'my-button',
    template: `
        <button (click)="handleClick($event)">
            <ng-content></ng-content>
        </button>
    `
})
export class MyButtonComponent {
    @Output() public onClick: EventEmitter<Event> = new EventEmitter();

    handleClick(e) {
        this.onClick.emit(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

该按钮的正常用例是用户附加一个onClick处理程序。但是,有些用户希望使用按钮作为链接,如下所示:

<my-button [routerLink]="'/dashboard'">Go to dashboard</my-button>
Run Code Online (Sandbox Code Playgroud)

在这种情况下我想做的是将渲染my-button为<a>元素而不是文字<button>。但为了做到这一点,我需要检测用户已将指令附加[routerLink]到它。

有什么办法可以做到这一点吗?

我知道我可以添加一个布尔@Input()属性来将渲染切换到<a>模式,但这感觉很笨拙。

pen*_*han 5

您必须使用@Optional并且@Host两者都位于@angular/core.

在你的my-button打字稿组件上,你需要像这样进行依赖注入:

export class MyButtonComponent implements OnInit {
  constructor(@Optional() @Host() routerLink: RouterLink) {
     console.log(routerLink)
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

然后在您的模板上,您可以检查是否routerLink为空并渲染<a>标签或<button>标签

编辑:

要使链接正常工作,您需要执行以下操作:

<a [routerLink]="routerLink.commands">
   Test
</a> 
Run Code Online (Sandbox Code Playgroud)

不幸的是,由于某种原因我无法<ng-content>在a标签中工作。

ng-content编辑2:无法工作的原因是由于ng-content组件中有多个,解决此问题的一种方法是使用 ng-template,例如:

<ng-container *ngIf="hasRouterLink">
  <a [routerLink]="routerLink.commands">
    <ng-container *ngTemplateOutlet="contentTpl"></ng-container>
  </a> 
</ng-container>


<ng-container *ngIf="!hasRouterLink">
  <button>
    <ng-container *ngTemplateOutlet="contentTpl"></ng-container> 
  </button> 
</ng-container>

<ng-template #contentTpl><ng-content></ng-content></ng-template>
Run Code Online (Sandbox Code Playgroud)