内容简介:在开发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
查看它的源码,如图:
发现nz-col其实是一个指令,就去angular上搜索了指令的内容
一、angular指令概览
在 Angular 中有三种类型的指令:
<yunzhi-data-list></yunzhi-data-list> nz-row,nz-col *ngFor,*ngIf
这三种指令中最常用的就是组件,所以我重点学习了后两种指令。
二、属性型指令
自定义属性型指令
目标:使用指令实现给html元素绑定背景色:
<button appHighlight = "yellow">高亮</button>
-
生成指令类文件,同生成组件一样,使用CLI命令即可
ng generate directive highlight
然后就会多了这两个文件:
-
在指令的逻辑部分:
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; } }
-
使用该指令:
<button appHighlight="yellow">高亮</button>
- 效果:
-
绑定多个属性:
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; } }
-
使用:
<button appHighlight="yellow" defaultColor="red">高亮</button>
<button appHighlight defaultColor="red">高亮</button>
selector:选择器
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' })
这样一来,当我绑定到其他元素时,编译器就会报错:
如果我不想使用默认的指令前缀 app
,而是换成其他的,如 yunzhi
,则如图修改 tslint.json
文件
修改后:
{ "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>
-
首先为了让指令更符合官方的规范,推荐在
tsLint.json
指令选择器使用格式修改为cameCase
,即默认设置"directive-selector": [ true, "attribute", "yunzhi", "camelCase" ]
@Directive({ selector: '[yunzhiUnless]' })
-
新建指令
unless
,注入TemplateRef,ViewContainerRef(没懂下面这句话,先跟着往下写就行)使用TemplateRef取得 <ng-template> 的内容,并通过ViewContainerRef来访问这个视图容器
export class UnlessDirective { constructor(private viewContainer: ViewContainerRef, private templateRef: TemplateRef<any>) { } }
-
使用@Inout将一个布尔值绑定到
yunzhiUnless
属性上,当condition为false,显示,为true,不显示@Input() set yunzhiUnless(condition: boolean) { if (!condition) { this.viewContainer.createEmbeddedView(this.templateRef); } else if (condition) { this.viewContainer.clear(); } }
-
在模板中使用该指令
<p *yunzhiUnless="condition">测试-p</p>
-
测试指令
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; }
效果:
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指令的实现后,发现在使用时减少了很多迷茫,有些以前不懂的细节也知道了为什么会这样,不过也发现自己还有好多不懂的地方,比如模板和容器,DOM的一些操作等。
以上所述就是小编给大家介绍的《angular 指令的学习》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Redis有序集合指令学习
- DOCKER学习_012:Dockerfile配置指令详解
- Nginx 学习系列(三) ------------- alias、root指令区别
- Android逆向之旅—最右App的签名算法解析(ARM指令学习回首篇)
- redis 用scan指令 代替keys指令(详解)
- vue 基本指令(四)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
群智能算法及其应用
高尚 / 中国水利水电出版社 / 2006-5 / 25.00元
《群智能算法及其应用》系统地描述了蚁群算法和粒子群优化算法的理论和实现技术及其应用,简单地介绍了鱼群算法。《群智能算法及其应用》着重强调各种算法的混合,讨论了蚁群算法与模拟退火算法的混合、蚁群算法与遗传算法的混合、蚁群算法与混沌理论混合、模拟退火算法、遗传算法与粒子群优化算法混合、混沌理论与粒子群优化算法的混合以及蚁群算法与粒子群优化算法的混合。书中还讨论了群智能算法在旅行商问题、武器一目标分配问......一起来看看 《群智能算法及其应用》 这本书的介绍吧!