一直不明白什么时候应用指令。
一个开源项目中的指令应用场景。
头部右上角有登陆信息,用户登陆后和未登录的情况,menu列表不同。
<!-- Show this for logged out users --> <ul *appShowAuthed="false" class="nav navbar-nav pull-xs-right"> <li class="nav-item"> <a class="nav-link" routerLink="/"> Home </a> </li> <li class="nav-item"> <a class="nav-link" routerLink="/login" routerLinkActive="active"> Sign in </a> </li> <li class="nav-item"> <a class="nav-link" routerLink="/register" routerLinkActive="active"> Sign up </a> </li> </ul> <!-- Show this for logged in users --> <ul *appShowAuthed="true" class="nav navbar-nav pull-xs-right"> <li class="nav-item"> <a class="nav-link" routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }"> Home </a> </li> <li class="nav-item"> <a class="nav-link" routerLink="/editor" routerLinkActive="active"> <i class="ion-compose"></i> New Article </a> </li> <li class="nav-item"> <a class="nav-link" routerLink="/settings" routerLinkActive="active"> <i class="ion-gear-a"></i> Settings </a> </li> <li class="nav-item"> <a class="nav-link" [routerLink]="['/profile', currentUser.username]" routerLinkActive="active"> <img [src]="currentUser.image" *ngIf="currentUser.image" class="user-pic" /> {{ currentUser.username }} </a> </li> </ul>
指令代码如下
import { Directive, Input, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { UserService } from '../core'; @Directive({ selector: '[appShowAuthed]' }) export class ShowAuthedDirective implements OnInit { constructor( private templateRef: TemplateRef<any>, private userService: UserService, private viewContainer: ViewContainerRef ) {} condition: boolean; ngOnInit() { this.userService.isAuthenticated.subscribe( (isAuthenticated) => { if (isAuthenticated && this.condition || !isAuthenticated && !this.condition) { this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } } ); } @Input() set appShowAuthed(condition: boolean) { this.condition = condition; } }
angular-realworld-example
目前的理解是构造函数中ViewContainerRef是当前指令,直接作为容器,
TemplateRef<any>是当前指令中包含的html直接作为模板添加
而且以上两个参数无论在构造函数中生命多少个还是同样的值,等有能力看源码的时候再看看。
测试结果如下
constructor( private userService: UserService, private templateRef: TemplateRef<any>, private templateRef1: TemplateRef<any>, private templateRef2: TemplateRef<any>, private viewContainer: ViewContainerRef, private viewContainer1: ViewContainerRef ) {} condition: boolean; ngOnInit() { this.userService.isAuthenticated.subscribe( (isAuthenticated) => { if (isAuthenticated && this.condition || !isAuthenticated && !this.condition) { this.viewContainer.createEmbeddedView(this.templateRef); this.viewContainer.createEmbeddedView(this.templateRef1); this.viewContainer.createEmbeddedView(this.templateRef2); this.viewContainer1.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } } ); }
ubuntu不会截图,出现了四个登陆menu和背景图片。
input参数貌似类似构造函数一样,只能通过html中使用指令的同时传递input,所以无法添加其他名称的input只能和selector名字一样,就像*ngIf也没有什么其他的参数。以后看源码
这里还有看到一种用法,给input时候可以使用set方法直接做一些逻辑处理。上次出现的一个7位字符串组成的一个code可以通过指令直接拆分成7个来进行表示。
*星号前缀提示 Angular 模板解析器
引出了ngif的原理
https://www.imwhite.com.cn/2019/09/angular-understand-structrual-directive/