zoukankan      html  css  js  c++  java
  • angular11源码探索四[指令源码示例篇]

    ng_class

    父传子

    set 的形式进行修改

    <input type="range" [(ngModel)]="num" min="1" max="4">
    <div appChColor [one]="num">
      hello world
    </div>
    
    @Directive({
      selector: '[appChColor]'
    })
    export class ChColorDirective {
    
      constructor(
        private el: ElementRef,
        private renderer: Renderer2
      ) {
        // this.changeColor('red')
      }
      // 设1,2,3,4对应三种不懂的颜色添加到
      obj={
        1:'#ccc',
        2:'#b41818',
        3:'#5e2caa',
        4:'#cb10ad'
      }
      @Input('one')
      set setValue(value) {
        this.renderer.setStyle(this.el.nativeElement,'color',this.obj[value])
      }
    
    }
    

    在查看NgClass 的时候竟然发现可以传set类型

    type NgClassSupportedTypes = string[]|Set<string>|{[klass: string]: any}|null|undefined;
    
      public add1 = new Set();
      this.add1.add('aaa');
    <div [ngClass]="add1">xxx</div>
    
    

    实验了下,学习到了

    let a = new Set('bbbaaabb bbbccc ddd  ccc ddd     aaaabcd');
    console.log([...a]);
    // [ 'b', 'a', ' ', 'c', 'd' ]
    

    使用方法

     
        <some-element [ngClass]="'first second'">...</some-element>
     
          <some-element [ngClass]="['first', 'second']">...</some-element>
     
          <some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>
    
         <some-element [ngClass]="stringExp|arrayExp|objExp">...</some-element>
    
        <some-element [ngClass]="{'class1 class2 class3' : true}">...</some-element>
       <div  class="{{'bbb'}}">xxx</div>
    	<div [class]="'foo'"></div>
    	发现一个有趣的东西
        <div class="aaa bbb ccc" [class.aaa]="bool">xxxx</div>
    	public bool=true;
    	[class.aaa] 用于判断 class aaa 的是否存在
    

    如果是字符串,清除空格变成数组

    typeof value === 'string' ? value.split(/s+/) : value;
    

    我们发现是通过_renderer ,进行添加删除class

    拿到DOM进行addClass,removeClass操作

     export class NgClass implements DoCheck {
         constructor(
          private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,
          private _ngEl: ElementRef, private _renderer: Renderer2) {}
     }
    
     private _toggleClass(klass: string, enabled: boolean): void {
        klass = klass.trim();
        if (klass) {
          klass.split(/s+/g).forEach(klass => {
            if (enabled) {
              this._renderer.addClass(this._ngEl.nativeElement, klass);
            } else {
              this._renderer.removeClass(this._ngEl.nativeElement, klass);
            }
          });
        }
      }
    

    ngFor

    <div *ngFor="let item of null">sss {{item}}</div>
    我们发现这个dom不生成
    
    <ul>
        <li *ngFor="let item of items as collection; index as i">	     	              {{i}}/{{collection.length}} - {{item}};
    	</li>
    </ul>
      items = ['a','b','c'];
    视图
    0/3 - a;
    1/3 - b;
    2/3 - c;
    
    <span *ngFor ="let item of items; let i=index">{{i}}</span>
    
    • $implicit: T:可迭代(ngForOf)中各个项目的值。
    • ngForOf: NgIterable<T>:可迭代表达式的值。当表达式比属性访问更复杂时(例如,使用异步管道()时)很有用。userStreams | async
    • index: number:当前项目在iterable中的索引。
    • count: number:可迭代的长度。
    • first: boolean:当项目是可迭代的第一项时为true。
    • last: boolean:当项目是可迭代的最后一个项目时为true。
    • even: boolean:当项目的可迭代索引为偶数时为true。
    • odd: boolean:当项目在可迭代项中具有奇数索引时为true。

    使用自定义模板

    <ng-container *ngFor="let item of items; template: tpl"></ng-container>
    <ng-template let-item let-i="index" #tpl>
        <p>{{i}}: {{item}};</p>
    </ng-template>
    
      items = ['a','b','c'];
    

    如果自定义模板为空就使用默认

    <ng-container *ngFor="let item of items; template: null">
      <div>{{item}}</div>
    </ng-container>
    
    template 里面的内容为空的
    

    简化版

    <ng-template ngFor let-item [ngForOf]="items" let-i="index">
      <li>...</li>
    </ng-template>
    

    ngIf

    运用于自定义模块,可以在页面展示内容
    <ng-template [ngIf]="bool">xxxx</ng-template>
    
      public bool: boolean = true;
    可以直接在值里面进行运算和输入函数
    <div *ngIf="isBool()">bbbbb</div>
    
    else 的正确使用
    
    <span *ngIf="booleanCondition; else elseBlock">TRUE</span>
    <ng-template #elseBlock>FALSE</ng-template>
    
    判断支持模块
    public booleanCondition=true
    
    <span *ngIf="booleanCondition; then thenBlock; else elseBlock"></span>
    <ng-template #thenBlock>THEN</ng-template>
    <ng-template #elseBlock>ELSE</ng-template>
    
    可以进行复杂的判断
    
    <span *ngIf="booleanCondition;
                then nestedBooleanCondition ? tplRef : null;
                else nestedBooleanCondition ? elseRef : null"></span>
            <ng-template #tplRef>Template</ng-template>
            <ng-template #elseRef>Template</ng-template>
            
    booleanCondition= true
    nestedBooleanCondition= true
    
    变通的形式
    <span *ngIf="bool; else isBool? b1 : b2">TRUE</span>
    <ng-template #b1>FALSE1</ng-template>
    <ng-template #b2>FALSE2</ng-template>
    
    bool=true;
    isBool=true;
    
    ---------
    <span *ngIf="bool; else elseBlock; let v">{{v}}</span>
    <ng-template #elseBlock>FALSE1</ng-template>  
    // v 展示的就是需要展示的变量
      public bool= 1;
    

    ngPlural

    添加删除DOM

    // 变化是当个值得时候用 `=value`
    <ul [ngPlural]="switchValue">
      <ng-template ngPluralCase="=0">
        <li>aaaaaaaaa.</li>
      </ng-template>
      <ng-template ngPluralCase="=1">
        <li>bbbbbbbbbbb.</li>
      </ng-template>
      <ng-template ngPluralCase="=sex">
        <li>xxxxxxxxxxxxx.</li>
      </ng-template>
    </ul>
    
    <button (click)="isPlural()">Click</button>
    
      public switchValue: number | string = 0;
    
      isPlural() {
        console.log(this.switchValue);
        if (this.switchValue === 0) {
          this.switchValue = 1;
        } else if (this.switchValue === 1) {
          this.switchValue = 'sex';
        } else if (this.switchValue === 'sex') {
          this.switchValue = 0;
        }
      }
    
    ===========
    值 number
    
    <ul [ngPlural]="switchValue">
      <ng-template ngPluralCase="0">
        <li>aaaaaaaaa.</li>
      </ng-template>
      <ng-template ngPluralCase="1">
        <li>bbbbbbbbbbb.</li>
      </ng-template>
    <ul>
     
    isPlural() {
        console.log(this.switchValue);
        if (this.switchValue === 0) {
          this.switchValue = 1;
        } else if (this.switchValue === 1) {
          this.switchValue = 0;
        }
      }
    
    ============
    可以使用 `ng-container` 标签  
    <ng-container [ngPlural]="switchValue">
      <ng-template ngPluralCase="0">
        aaaaaaaaa.
      </ng-template>
      <ng-template ngPluralCase="1">
        bbbbbbbbbbb.
       </ng-template>    
    </ng-container>
    
    =========
          如果[ngPlural]的值,找不到,就使用 other的内容
     <ng-template ngPluralCase="other"><li>我的默认内容</li></ng-template>      
    

    源码中对这个做了解释

    export function getPluralCategory(
        value: number, cases: string[], ngLocalization: NgLocalization, locale?: string): string {
      let key = `=${value}`;
    
      if (cases.indexOf(key) > -1) {
        return key;
      }
    
      key = ngLocalization.getPluralCategory(value, locale);
    
      if (cases.indexOf(key) > -1) {
        return key;
      }
     // 默认的使用
      if (cases.indexOf('other') > -1) {
        return 'other';
      }
    // 报错了
      throw new Error(`No plural message found for value "${value}"`);
    }
    

    当时不理解,原来是做了国际化

    export enum Plural {
      Zero = 0,
      One = 1,
      Two = 2,
      Few = 3,
      Many = 4,
      Other = 5,
    }
      switch (plural) {
          case Plural.Zero:
            return 'zero';
          case Plural.One:
            return 'one';
          case Plural.Two:
            return 'two';
          case Plural.Few:
            return 'few';
          case Plural.Many:
            return 'many';
          default:
            return 'other';
        }
    

    使用的时候

    <ul [ngPlural]="switchValue">
    
      <ng-template ngPluralCase="one"> 
        <li>111111111111111</li>
      </ng-template>
      <ng-template ngPluralCase="few">
        <li>you have a few messages.</li>  
      </ng-template >
    </ul>
    
    switchValue=1 (one) 
    		  =3  (few)
    

    ngStyle

    // .px   属性的写法,用于写尺寸
    <div [ngStyle]="{backgroundColor:'red','100px'}">xxxxxxxxx</div>
    <div [ngStyle]="{'background-color':'red','width.px':100}">xxxxxxxxx</div>
    
    
    

    ngSwitch

    <ul [ngSwitch]="num1">
      <li *ngSwitchCase="num2">aaaaa</li>
      <li *ngSwitchCase="num3">bbbb</li>
      <!--默认-->
      <li *ngSwitchDefault>ccccc</li>
    </ul>
    
      num1 = 1;
      num2 = 2;
      num3 = 3;
    ==============
    <ul [ngSwitch]="'a'">
      <li *ngSwitchCase="'a'">aaaaa</li>
      <li *ngSwitchCase="'b'">bbbb</li>
      <!--默认-->
      <li *ngSwitchDefault>ccccc</li>
    </ul>
    
    ==============
    <ul [ngSwitch]="'a'">
      <li *ngSwitchCase="'a'">aaaaa
           <ng-container  [ngTemplateOutlet]="foo"></ng-container>
    <!--       <span *ngSwitchDefault>默认内容1</span>-->
      </li>
      <li *ngSwitchCase="'b'">bbbb
        <ng-container [ngTemplateOutlet]="bar"></ng-container>
      </li>
      <!--默认-->
      <li *ngSwitchDefault>ccccc</li>
    </ul>
    <button (click)="isPlural()">Click</button>
    <ng-template #foo>
      <span>Foo</span>
    </ng-template>
    <ng-template #bar>
      <span>Bar</span>
    </ng-template>
    
    ========================
    
    <ul [ngSwitch]="'b'">
      <li *ngSwitchCase="'a'"  [ngSwitch]="true">aaaaa
    <!--    [ngSwitch] 就开始第二轮子判断-->
    <!--    [ngSwitch]="true"  展示ng-container 的内容,  为false,展示默认的内容-->
           <ng-container *ngSwitchCase="true"  [ngTemplateOutlet]="foo"></ng-container>
           <span *ngSwitchDefault>默认内容1</span>
      </li>
      <li *ngSwitchCase="'b'"  [ngSwitch]="true">bbbb
        <ng-container *ngSwitchCase="true" [ngTemplateOutlet]="bar"></ng-container>
        <span *ngSwitchDefault>默认内容2</span>
    
      </li>
      <!--默认-->
      <li *ngSwitchDefault>ccccc</li>
    </ul>
    

    ngTemplate

    <ng-container *ngTemplateOutlet="tap;"></ng-container>
    <ng-template #tap>{{obj.sex}}</ng-template>
    <!--  obj={sex:'bbb'}  -->
    =============
    <ng-template #tpl>foo</ng-template>
    <div [ngTemplateOutlet]="tpl"></div>
    
    ==========
    <ng-container *ngTemplateOutlet="tpl; context: obj"></ng-container>
    // 设置一个变量等于这个属性
    <ng-template let-foo="sex" #tpl>{{foo}}</ng-template>
      obj={sex:'bbb'}
    
    ===========
    <ng-template [ngTemplateOutlet]="tpl" [ngTemplateOutletContext]="{foo: values}"></ng-template>
    <ng-template let-foo="foo" #tpl>{{foo}}</ng-template>
    
      values=2;
    
    ==============
    转化你容易看懂的模式
    <ng-template [ngTemplateOutlet]="tpl" [ngTemplateOutletContext]="obj"></ng-template>
    <ng-template let-foo="sex" #tpl>{{foo}}</ng-template>
    
      obj={sex:'bbb'}
    
    =============
    <ng-template #testTemplate>test</ng-template>
    <!--第一种-->
    <ng-template [ngTemplateOutlet]="testTemplate"></ng-template>
    <!--第二种-->
    <ng-template *ngTemplateOutlet="testTemplate"></ng-template>
    
    
    

    决定自己的高度的是你的态度,而不是你的才能

    记得我们是终身初学者和学习者

    总有一天我也能成为大佬

  • 相关阅读:
    自我介绍
    目前流行的源程序版本管理软件和项目管理软件的优缺点
    四月是你的谎言
    软件分析(Mobile Apps )--百词斩
    程序扩展
    超级无敌小学四则运算题目程序
    4组 团队展示
    2020面向对象设计与构造 第四单元 & 课程 博客总结
    2020面向对象设计与构造 第三单元 博客总结
    2020面向对象设计与构造 第二单元 博客总结
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14123475.html
Copyright © 2011-2022 走看看