Angular 6:更改外部库的代码仅适用于 'ng serve' 而不适用于 'ng build'
Angular 6: Changing the code of an external library only works with 'ng serve' and not with 'ng build'
我正在开发一个项目,我已经为它安装了一个外部库。 ng-select library by Bas van den Berg,效果很好,但需要库与 onPush 更改检测策略一起使用。我需要添加一个 ChangeDetectorRef,因此我可以使用 markForCheck()。
所以我想我会转到 ng-select.es5.js 文件并从 @angular/core 导入 ChangeDetectorRef,定义并初始化 changeDetectorRef 并使用 markForCheck () 在需要的地方,像这样:
import { Component, ContentChild, ElementRef, EventEmitter, HostListener, Input, NgModule, Output, ViewChild, ViewEncapsulation, forwardRef, ChangeDetectorRef } from '@angular/core';
...
var SelectComponent = /** @class */ (function () {
/**
* @param {?} hostElement
* @param {?} changeDetectorRef
*/
function SelectComponent(hostElement, changeDetectorRef) {
this.hostElement = hostElement;
this.changeDetectorRef = changeDetectorRef;
console.log('constructor', this.changeDetectorRef, changeDetectorRef, ChangeDetectorRef);
...
SelectComponent.ctorParameters = function () {
return [
{ type: ElementRef, },
{ type: ChangeDetectorRef, }
];
};
...
SelectComponent.prototype.updateState = function (functionName) {
console.log(functionName)
var _this = this;
setTimeout(function () {
_this.changeDetectorRef.markForCheck();
});
};
现在,当我在项目中执行 'ng serve' 时,我可以看到 markForCheck() 得到正确执行,但是如果我执行 'ng build --aot' 或 'ng build --prod',我会收到此错误留言:
ERROR TypeError: Cannot read property 'markForCheck' of undefined
所以经过一些调试,我尝试在构造函数中记录 this.changeDetectorRef。在本地使用 'ng serve 它只会记录正确的内容,但在 'ng build' 中它会记录未定义的内容。
这怎么可能? 'ng serve'和'ng build'在编译上有区别吗?我需要将此代码放在其他地方吗?
编辑:如您所见,还有一个名为 hostElement 的 ElementRef 确实有效,并且与 changeDetectorRef 一样完全定义和初始化。
Edit2:好的,我在没有 --aot 或 --prod 的情况下再次尝试,然后我没有错误。但我需要它与 --prod 一起工作。我怎样才能做到这一点?所以更好的问题是:常规 'ng build' 和 'ng build --prod' 之间有什么区别?
好吧,我终于找到发生了什么事了。
https://github.com/angular/angular/issues/11262#issuecomment-244472000
显然您需要在“*.metadata.json”文件中添加您使用的库。
我正在开发一个项目,我已经为它安装了一个外部库。 ng-select library by Bas van den Berg,效果很好,但需要库与 onPush 更改检测策略一起使用。我需要添加一个 ChangeDetectorRef,因此我可以使用 markForCheck()。
所以我想我会转到 ng-select.es5.js 文件并从 @angular/core 导入 ChangeDetectorRef,定义并初始化 changeDetectorRef 并使用 markForCheck () 在需要的地方,像这样:
import { Component, ContentChild, ElementRef, EventEmitter, HostListener, Input, NgModule, Output, ViewChild, ViewEncapsulation, forwardRef, ChangeDetectorRef } from '@angular/core';
...
var SelectComponent = /** @class */ (function () {
/**
* @param {?} hostElement
* @param {?} changeDetectorRef
*/
function SelectComponent(hostElement, changeDetectorRef) {
this.hostElement = hostElement;
this.changeDetectorRef = changeDetectorRef;
console.log('constructor', this.changeDetectorRef, changeDetectorRef, ChangeDetectorRef);
...
SelectComponent.ctorParameters = function () {
return [
{ type: ElementRef, },
{ type: ChangeDetectorRef, }
];
};
...
SelectComponent.prototype.updateState = function (functionName) {
console.log(functionName)
var _this = this;
setTimeout(function () {
_this.changeDetectorRef.markForCheck();
});
};
现在,当我在项目中执行 'ng serve' 时,我可以看到 markForCheck() 得到正确执行,但是如果我执行 'ng build --aot' 或 'ng build --prod',我会收到此错误留言:
ERROR TypeError: Cannot read property 'markForCheck' of undefined
所以经过一些调试,我尝试在构造函数中记录 this.changeDetectorRef。在本地使用 'ng serve 它只会记录正确的内容,但在 'ng build' 中它会记录未定义的内容。
这怎么可能? 'ng serve'和'ng build'在编译上有区别吗?我需要将此代码放在其他地方吗?
编辑:如您所见,还有一个名为 hostElement 的 ElementRef 确实有效,并且与 changeDetectorRef 一样完全定义和初始化。
Edit2:好的,我在没有 --aot 或 --prod 的情况下再次尝试,然后我没有错误。但我需要它与 --prod 一起工作。我怎样才能做到这一点?所以更好的问题是:常规 'ng build' 和 'ng build --prod' 之间有什么区别?
好吧,我终于找到发生了什么事了。
https://github.com/angular/angular/issues/11262#issuecomment-244472000
显然您需要在“*.metadata.json”文件中添加您使用的库。