angular 指令的学习

栏目: 编程语言 · AngularJS · 发布时间: 6年前

内容简介:在开发alice项目中,使用了阿里的ng-zorro框架,所以会经常遇到很多框架自己写的属性,例如下面的栅格:其中的nz-row,nz-col,以及nzSpan就是框架自定义的html属性,但他们究竟是什么,又是怎么实现的,我却从来没有想过,所以,趁着本周学习时间比较充裕,就去探索了一下。首先,在webstorm通过

前言

在开发alice项目中,使用了阿里的ng-zorro框架,所以会经常遇到很多框架自己写的属性,例如下面的栅格:

<div nz-row>
    <div nz-col [nzSpan]="4">
        xxx
    </div>
</div>

其中的nz-row,nz-col,以及nzSpan就是框架自定义的html属性,但他们究竟是什么,又是怎么实现的,我却从来没有想过,所以,趁着本周学习时间比较充裕,就去探索了一下。

首先,在webstorm通过 Ctrl + 鼠标点击 nz-col 查看它的源码,如图:

angular 指令的学习

发现nz-col其实是一个指令,就去angular上搜索了指令的内容

一、angular指令概览

在 Angular 中有三种类型的指令:

<yunzhi-data-list></yunzhi-data-list>
nz-row,nz-col
*ngFor,*ngIf

这三种指令中最常用的就是组件,所以我重点学习了后两种指令。

二、属性型指令

自定义属性型指令

目标:使用指令实现给html元素绑定背景色:

<button appHighlight = "yellow">高亮</button>

angular 指令的学习

  1. 生成指令类文件,同生成组件一样,使用CLI命令即可

    ng generate directive highlight

    然后就会多了这两个文件:

    angular 指令的学习

  2. 在指令的逻辑部分:

    export class HighlightDirective implements OnInit {
    // 使用@input绑定传给指令的值
      @Input('appHighlight') highlightColor: string;
      constructor(private el: ElementRef) {    //  ElementRef就是该指令绑定的宿主元素
      }
    
      ngOnInit(): void {
      // 设置该元素的css样式的背景色为输入值
        this.el.nativeElement.style.backgroundColor = this.highlightColor;
      }
    }
  3. 使用该指令:

    <button appHighlight="yellow">高亮</button>
  4. 效果:
    angular 指令的学习
  5. 绑定多个属性:

    export class HighlightDirective implements OnInit {
      @Input('appHighlight') highlightColor: string;
      @Input() defaultColor: string;    // 默认颜色
      constructor(private el: ElementRef) {
      }
    
      ngOnInit(): void {
      // 如果highlightColor有值,则绑定highlightColor,没有则绑定defaultColor
        this.el.nativeElement.style.backgroundColor = this.highlightColor || this.defaultColor;
      }
    }
  6. 使用:

    <button appHighlight="yellow" defaultColor="red">高亮</button>

    angular 指令的学习

    <button appHighlight defaultColor="red">高亮</button>

    angular 指令的学习

selector:选择器

如果我写的指令不想被人乱用,比如上述指令我只想在button中生效,就要用到指令的选择器( selector

)了。

一般我们命令生成指令文件后会有如下默认的代码段:

@Directive({
  selector: '[appHighlight]'
})

这个selector里的字符串就是我们使用指令绑定到宿主元素的规则,或者说实例化指令对象的规则。

angular文档提供的规则表如下:

  • element-name:根据元素名选取。
  • .class:根据类名选取。
  • [attribute]:根据属性名选取。
  • [attribute=value]:根据属性名和属性值选取。
  • :not(sub_selector):只有当元素不匹配子选择器 sub_selector 的时候才选取。
  • selector1, selector2:无论 selector1 还是 selector2 匹配时都选取。

例如,默认的绑定方法就是把该指令当成属性,如: <button appHighlight>高亮</button>

如果我想只绑定给button,就可以这样写:

@Directive({
  selector: '[appHighlight] button'
})

这样一来,当我绑定到其他元素时,编译器就会报错:

angular 指令的学习

如果我不想使用默认的指令前缀 app ,而是换成其他的,如 yunzhi ,则如图修改 tslint.json 文件

angular 指令的学习

修改后:

{
    "extends": "../tslint.json",
    "rules": {
        "directive-selector": [
            true,
            "attribute",
            "yunzhi",
            "kebab-case"
        ],
        "component-selector": [
            true,
            "element",
            "app",
            "kebab-case"
        ]
    }
}

指令选择器也修改前缀:

@Directive({
  selector: '[yunzhi-highlight] button'
})

使用指令:

<button yunzhi-highlight>高亮</button>

三、结构型指令

自定义结构型指令

目标:编写一个 yunzhiUnless 指令,作用与ngIf相反,当变量值为false,显示宿主元素,为true则移除不显示。

<p *yunzhiUnless="condition">测试-p</p>

angular 指令的学习

  1. 首先为了让指令更符合官方的规范,推荐在 tsLint.json 指令选择器使用格式修改为 cameCase ,即默认设置

    "directive-selector": [
         true,
         "attribute",
         "yunzhi",
         "camelCase"
     ]
    @Directive({
      selector: '[yunzhiUnless]'
    })
  2. 新建指令 unless ,注入TemplateRef,ViewContainerRef(没懂下面这句话,先跟着往下写就行)

    使用TemplateRef取得 <ng-template> 的内容,并通过ViewContainerRef来访问这个视图容器

    export class UnlessDirective {
         constructor(private viewContainer: ViewContainerRef,
                 private templateRef: TemplateRef<any>) { }
     
     }
  3. 使用@Inout将一个布尔值绑定到 yunzhiUnless 属性上,当condition为false,显示,为true,不显示

    @Input()
      set yunzhiUnless(condition: boolean) {
        if (!condition) {
          this.viewContainer.createEmbeddedView(this.templateRef);
        } else if (condition) {
          this.viewContainer.clear();
        }
      }
  4. 在模板中使用该指令

    <p *yunzhiUnless="condition">测试-p</p>
  5. 测试指令

    html:

    <p>
      condition={{condition | json}}
    </p>
    
    <label for="show">显示</label>
    <input id="show" type="radio" [value]="false" [(ngModel)]="condition">
    <label for="unshow">不显示</label>
    <input id="unshow" type="radio" [value]="true" [(ngModel)]="condition">
    
    <p *yunzhiUnless="condition">测试-p</p>

    ts:

    export class TestComponent {
      condition = false;
    }

效果:

angular 指令的学习

TemplateRef

如名字所示,TemplateRef 用于表示 模板的引用 ,但我们注意到这里并没有使用 ng-template ,为什么还能引用它呢?

这是因为 *yunzhiUnless 其实是一个语法糖

<p *yunzhiUnless="condition">测试-p</p>

等同于:

<ng-template [yunzhiUnless]="condition">
  <p>测试-ng-template</p>
</ng-template>

如果没有使用结构型指令,而仅仅把一些别的元素包装进 <ng-template> 中,那些元素就是不可见的。

ViewContainerRef

ViewContainerRef 用于表示容器的引用,通常是span,div等

ViewContainerRef 对象提供了 createEmbeddedView() 方法,该方法接收 TemplateRef 对象作为参数,并将模板中的内容作为容器 (comment 元素) 的兄弟元素,插入到页面中。

简单理解就是如下图, templateRef 指向 ng-template 标签, viewContainer 指向 ng-container 标签

angular 指令的学习

总结

简单的了解了angular指令的实现后,发现在使用时减少了很多迷茫,有些以前不懂的细节也知道了为什么会这样,不过也发现自己还有好多不懂的地方,比如模板和容器,DOM的一些操作等。


以上所述就是小编给大家介绍的《angular 指令的学习》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JSP 2.0技术手册

JSP 2.0技术手册

杜远君、林康司、林上杰 / 湖北教育出版社,电子工业出版社 / 2004-5-1 / 59.0

本书图文并茂,以丰富的实例为引导,全面介绍了主流的Java Web开发技术——JSP 2.0,重点介绍Java在展示层的两项重要技术:Java Servlet与JavaServer Pages。它们是最重要的Java核心技术。对这两项技术的深入了解,将有助于您未来对于JavaServer Faces(JSF)技术以及Java Web Services技术的学习。 本书分为三大部分,前......一起来看看 《JSP 2.0技术手册》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具