zoukankan      html  css  js  c++  java
  • [Angular] @ViewChildren and QueryLists (ngAfterViewInit)

    When you use @ViewChildren, the value can only be accessable inside ngAfterViewInit lifecycle. This is somehow different from @ViewChild, which value can be accessed from ngAfterContentInit lifecycle.

    import { Component, ChangeDetectorRef, Output, ViewChildren, AfterViewInit, EventEmitter, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
    
    import { AuthRememberComponent } from './auth-remember.component';
    import { AuthMessageComponent } from './auth-message.component';
    
    import { User } from './auth-form.interface';
    
    @Component({
      selector: 'auth-form',
      template: `
        <div>
          <form (ngSubmit)="onSubmit(form.value)" #form="ngForm">
            <ng-content select="h3"></ng-content>
            <label>
              Email address
              <input type="email" name="email" ngModel>
            </label>
            <label>
              Password
              <input type="password" name="password" ngModel>
            </label>
            <ng-content select="auth-remember"></ng-content>
            <auth-message 
              [style.display]="(showMessage ? 'inherit' : 'none')">
            </auth-message>
            <auth-message 
              [style.display]="(showMessage ? 'inherit' : 'none')">
            </auth-message>
            <auth-message 
              [style.display]="(showMessage ? 'inherit' : 'none')">
            </auth-message>
            <ng-content select="button"></ng-content>
          </form>
        </div>
      `
    })
    export class AuthFormComponent implements AfterContentInit, AfterViewInit {
    
      showMessage: boolean;
    
      @ViewChildren(AuthMessageComponent) message: QueryList<AuthMessageComponent>;
    
      @ContentChildren(AuthRememberComponent) remember: QueryList<AuthRememberComponent>;
    
      @Output() submitted: EventEmitter<User> = new EventEmitter<User>();
    
      constructor(private cd: ChangeDetectorRef) {}
    
      ngAfterViewInit() {
        console.log("this.message:", this.message); // QueryList {...}
        if (this.message) {
          this.message.forEach((message) => {
            message.days = 30;
          });
          this.cd.detectChanges();
        }
      }
    
      ngAfterContentInit() {
        console.log("this.message:", this.message); // undefined
        if (this.remember) {
          this.remember.forEach((item) => {
            item.checked.subscribe((checked: boolean) => this.showMessage = checked);
          });
        }
      }
    
      onSubmit(value: User) {
        this.submitted.emit(value);
      }
    
    }

    Here we try to modify the value inside ngAfterViewInit lifecycle. but in developement mode, there is change detection error! We cannot modify the 'messages.day' after view init. 

    We can bypass this problem by using 'ChangeDetectRef'.

    this.cd.detectChanges();

    To tell Angular change detection everything is fine. And this error won't show up in production mode, only in development mode.

  • 相关阅读:
    [ts]类
    【跨域】jsonp的实现
    [ts]基础类型
    在Crystal Report中将数字转为英文
    合并 GridView 的单元格
    C#动态加载DLL
    在网页处理按键事件
    SQL Server 2005 中新CTE语法 递归性能测试
    连接远程服务器共享
    Asp.net 文件下载
  • 原文地址:https://www.cnblogs.com/Answer1215/p/6417976.html
Copyright © 2011-2022 走看看