乐趣区

关于angular:angular-指令

咱们之前并没有接触过指令,然而可能对这个词并不生疏,例如咱们常常会看到这样的编译器报错:

那么咱们由此也能够大抵猜测出指令是在那里应用的了。

要想进一步理解指令就须要去官网文档中去理解了。

import {Directive} from '@angular/core';

@Directive({selector: '[appCheckSingle]'
})
export class CheckSingleDirective {}

首先就是如何在组件中应用指令,也就是咱们所相熟的 selector, 这里的selector 规定与组件不同,组件在应用是是间接作为标签来应用如:

<app-xxxSelect></app-xxxSelect>

而指令是作为标签的属性来应用的,也就是说下面的指令要这样来申明此标签用到了这个指令。

  <div appCheckSingle></div>

在官网文档中咱们还能够理解到咱们还能够靠 selector 来设置让哪些标签能够调用该指令。比方咱们只想让类型为输入框的 input 标签调用此指令:

@Directive({selector: 'input[type=text]'
})
export class CheckSingleDirective implements OnInit, OnDestroy {
.  .  .
  @Input()
  appCheckSingle = {} as {id: number};
.  .  .

}

然而上述性能尽管能够失常实现然而编译器会产生报错:

ESLint: The selector should start with one of these prefixes: &quot;app&quot; (https://angular.io/guide/styleguide#style-02-08) (@angular-eslint/directive-selector)

说咱们前缀不符合要求,这是因为在 angular 配置文件中规定了其默认格局,将下述代码中 "prefix": "app", 正文掉就不会产生报错,可能是 angular 在版本更新中漠视了此点或是默认状况下不容许这么操作?

配置文件 .eslintrc.json 中有其默认格局:

"@angular-eslint/directive-selector": [
          "error",
          {
            "type": "attribute",
            "prefix": "app",
            "style": "camelCase"
          }
        ]

1、须要是属性
2、以 app 为前缀
3、命名格局为小驼峰

咱们在官网文档中还能够得悉指令和组件一样也有着生命周期,也能够通过 @input、@outPut 来和组件进行数据的传递。

那么如果一个组件中退出了多个指令那么这多个指令间能够间接进行互动吗?
答案是能够,能够通过 exportAs 来将此指令抛出。

@Directive({selector: '[appCheckAll]',
  exportAs: 'appCheckAll'
})

咱们在应用时像上面这样即可:

上面来介绍一下如何用指令实现单选和全选:

首先就是如何传入选项信息,这里和之前靠组件实现单全选组件的形式不同,并不需要对前台实体退出是否被抉择属性,间接传入所需选项即可。

也就是说咱们在组件中只需筹备这些数据即可:

  public items = [{id: 2}, {id: 1}, {id: 3}, {id: 4}] as {id: number}[];
  public selectedItems = [];
<div>
  <label><input type="checkbox" [appCheckAll]="items"
          [checkedItems]="selectedItems"
          #checkAll="appCheckAll"/> 全选 </label>
</div>
<div *ngFor="let item of items">
  <label><input type="checkbox" [appCheckSingle]="item"
                [checkAllDirective]="checkAll"/>
                单选
  </label>
</div>

因为这并不是组件而是指令所以只有将 selectedItems 传入就能够在指令里进行相应操作就能够反馈到组件中,并不需要像子组件向父组件那样进行弹值。就像 formcontrol 与 input 标签进行绑定时所输出的信息能够间接传入 formcontrol 中那样。

而后咱们要做的就是怎么在指令中获取所绑定标签的的抉择状况用于初始化,比方怎么得悉指令对应的抉择框是否被选中。这时候就须要获取宿主(即绑定的标签)。

  /**
   * 宿主
   */
  checkboxElement: HTMLInputElement;

  constructor(private elementRef: ElementRef<HTMLElement>) {this.checkboxElement = elementRef.nativeElement as HTMLInputElement;}

其中就蕴含了抉择框的抉择信息
而后就是要获取实时的互动信息,尽管咱们晓得了初始状况下的抉择状况,然而当宿主信息有变动时咱们怎么获取呢。
angular 还给咱们提供了能够侦听 DOM 事件的装璜器。

@HostListener('click')
  onClick()

比方像这样申明就能够在宿主收回 click 事件时调用指令中的 onClick 办法。

如果想要在单选指令中获取多选指令信息或是管制多选靠多选指令 exportAs 进行援用即可。

因为多选指令能够间接由 exportAs 传递给单选指令才使得单选指令也能够对 selectedItems 进行解决,能够订阅多选组件的弹射器来获取其弹射的内容。

只后咱们的逻辑就如下图所示:

通过此次对指令的应用又取得了一种新的解决问题的办法,对于相似抉择框的问题能够不借助于批改前台实体来进行传递值。绝对于组件来说更加灵便,也更便于应用和书写(因为指令只须要一个 ts 文件即可)。

退出移动版