指令的一个应用 这个东西叫属性指令尴尬

一直不明白什么时候应用指令。

一个开源项目中的指令应用场景。

头部右上角有登陆信息,用户登陆后和未登录的情况,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>&nbsp;New Article
        </a>
      </li>

      <li class="nav-item">
        <a class="nav-link"
          routerLink="/settings"
          routerLinkActive="active">
          <i class="ion-gear-a"></i>&nbsp;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/

原文地址:https://www.cnblogs.com/have-a-try/p/13198523.html