ng2-ExpressionChangedAfterItHasBeenCheckedError

ng2-ExpressionChangedAfterItHasBeenCheckedError

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked on ng 4

值在checked完毕后却发生了变化的官方说明,以下内容引自Angular-issue-17572

This seems to keep going on and on even though all of the answers and advice has already been posted above.
1.The right way to fix this is to re-architect/restructure your components and data handling to work with a single change detection pass from the top down. This means that no child component may change a value that is used in the template of a parent component. Re-evaluate what you have built and verify that the data flows only in one direction, down the component tree. This may be as simple as moving your code out of ngAfterViewInit and into ngOnInit in some cases.
2.this.changeDetectorRef.detectChanges(); is the official and recognized way for handling this in the less than 5% of cases where the first step is problematic.

Other notes:
1.Be very careful when doing anything in ngAfterViewInit as changing values that are used in the DOM can cause this error.
2.Be very careful when using any of the Check or Checked lifecycle hooks as they may be called on every change detection cycle.
3.setTimeout can work around this, but the two solutions above are preferred.
4.Ignoring this error in dev mode and being happy that production mode “fixes” the error is not valid as explained above. These checks are not made in prod mode, but your prod mode code is still leaving changes undetected and causing the view and data to be out of sync. This can be harmless in some cases, but can lead to data/view corruption and worse problems if ignored.
5.One way data flow hasn’t really changed a lot in Angular, so posting that you hit this in version X of Angular isn’t too helpful.
6.Adding more lifecycle hooks or states is not a solution to this. Developers would just add code that violates one way data flow into those hooks and trigger this same error.

Finally, just remember that this error is not indicating a problem with Angular. This error is here to let you know that you have done something wrong in your code and that you are violating the one way data flow system that makes Angular fast and efficient.

The posts above and many blog posts go more deeply into this and are worth reading as you should understand this one way data flow model and how to build components and pass data within it.

工作记录-CSS换行-2018.8.15

word-break将单词分开

 word-break: break-all;

white-space文本整体的换行

 white-space: pre-wrap;

工作记录-手动触发onresize2018.8.12

const ev = new Event('resize', { bubbles: true, cancelable: false });
window.dispatchEvent(ev);

MDN

ng2-NgZone和Renderer2

在Angular中使用Echart为何cpu占用高
了解NgZone

import {  NgZone, Renderer2 } from '@angular/core';
// Renderer2 实验性功能

{
    this._renderer.setStyle(dom, 'width', width);
    this._renderer.setStyle(dom, 'height', height || 'auto');

    // 将echart的初始化脱离NgZone的监控,以免造成大量的cpu占用
    this._zone.runOutsideAngular(() => {
      this.chartInstance = this.chartInstance || echarts.init(_dom, 'ascm');
      this.chartInstance.setOption(this.eoption);
      this.firstInit = false;
      this.eloading = false;
    });
}

ng2-angular.json与自定义打包

"configurations": {
  "production": {
    "optimization": true,
    "outputHashing": "all",
    "sourceMap": false,
    "extractCss": true,
    "namedChunks": false,
    "aot": true,
    "extractLicenses": true,
    "vendorChunk": false,
    "buildOptimizer": true,
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ]
  },
  "tmp-prod-mode": {
    "optimization": true,
    "outputHashing": "all",
    "sourceMap": false,
    "extractCss": true,
    "namedChunks": false,
    "aot": true,
    "extractLicenses": true,
    "vendorChunk": false,
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ]
  }
}

configurations节点中的两个属性使用方式,以下即为自定义配置打包命令。
其中 buildOptimizer=true,该优化命令会导致代码出现 l.ngOnDestory is not a function的问题。
以以下命令来避免。

ng build --c tmp-prod-mode

ng2-ChangeDetectionStrategy提升性能

import { Component, OnInit, ViewEncapsulation, ChangeDetectionStrategy, Input, ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'scm-side-menu',
  templateUrl: './side-menu.component.html',
  styleUrls: ['./side-menu.component.scss'],
  encapsulation: ViewEncapsulation.None, // 增加该元数据则会让该组件的样式应用到整个app
  changeDetection: ChangeDetectionStrategy.OnPush
})

constructor(
  private cd:ChangeDetectorRef) { }

public data = []; // 此data已在页面绑定html
public clickBtn(item){
  this.data.push(item);
  this.data = JSON.parse(JSON.stringify(this.data)); // clone数组
  this.cd.detectChanges(); // 在需要更新视图时手动触发ng的检测
}

利用这个机制可以提高性能。避免ng去全部检测(ng2默认是会去检测所有的页面节点)。