diff --git a/src/jigsaw/common/directive/upload/upload.directive.ts b/src/jigsaw/common/directive/upload/upload.directive.ts index fa10eb5eb8..ffae4913bf 100644 --- a/src/jigsaw/common/directive/upload/upload.directive.ts +++ b/src/jigsaw/common/directive/upload/upload.directive.ts @@ -1,4 +1,16 @@ -import {Component, Directive, ElementRef, EventEmitter, HostListener, Input, OnDestroy, Optional, Output, Renderer2} from "@angular/core"; +import { + ChangeDetectionStrategy, + Component, + Directive, + ElementRef, + EventEmitter, + HostListener, + Input, + OnDestroy, + Optional, + Output, + Renderer2 +} from "@angular/core"; import {HttpClient} from "@angular/common/http"; import {TranslateService} from "@ngx-translate/core"; import { @@ -50,7 +62,7 @@ export class JigsawUploadDirective extends JigsawUploadBase implements OnDestroy public fileVerify: string; @Input('uploadAdditionalFields') - public additionalFields: {[prop: string]: string}; + public additionalFields: { [prop: string]: string }; @Input('uploadMinSize') public minSize: number; @@ -235,10 +247,12 @@ export class JigsawUploadDirective extends JigsawUploadBase implements OnDestroy - + - ` + `, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawUploadFileInfoList extends AbstractJigsawComponent implements IPopupable { public answer: EventEmitter; diff --git a/src/jigsaw/pc-components/alert/alert.ts b/src/jigsaw/pc-components/alert/alert.ts index 37e987cde6..b907f0296c 100644 --- a/src/jigsaw/pc-components/alert/alert.ts +++ b/src/jigsaw/pc-components/alert/alert.ts @@ -1,4 +1,20 @@ -import { Component, ContentChildren, ElementRef, EventEmitter, Input, NgModule, Output, QueryList, Renderer2, Type, ViewChild, Directive, NgZone } from "@angular/core"; +import { + Component, + ContentChildren, + ElementRef, + EventEmitter, + Input, + NgModule, + Output, + QueryList, + Renderer2, + Type, + ViewChild, + Directive, + NgZone, + ChangeDetectionStrategy, + Injector +} from "@angular/core"; import {CommonModule} from "@angular/common"; import {TranslateModule, TranslateService} from "@ngx-translate/core"; import { @@ -24,11 +40,14 @@ export enum AlertLevel { templateUrl: 'alert.html', host: { '[class.jigsaw-alert-host]': 'true' - } + }, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawAlert extends AbstractDialogComponentBase { - constructor(protected renderer: Renderer2, protected elementRef: ElementRef, protected _zone: NgZone) { - super(renderer, elementRef, _zone); + constructor(protected renderer: Renderer2, protected elementRef: ElementRef, protected _zone: NgZone, + // @RequireMarkForCheck 需要用到,勿删 + protected _injector: Injector) { + super(renderer, elementRef, _zone, _injector); } @Output() @@ -204,7 +223,8 @@ export abstract class JigsawCommonAlert extends DialogBase { @Component({ templateUrl: 'common-alert.html', - selector: 'jigsaw-info-alert, j-info-alert' + selector: 'jigsaw-info-alert, j-info-alert', + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawInfoAlert extends JigsawCommonAlert { constructor(protected _renderer: Renderer2, protected _elementRef: ElementRef) { @@ -246,7 +266,8 @@ export class JigsawInfoAlert extends JigsawCommonAlert { @Component({ templateUrl: 'common-alert.html', - selector: 'jigsaw-warning-alert, j-warning-alert' + selector: 'jigsaw-warning-alert, j-warning-alert', + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawWarningAlert extends JigsawCommonAlert { constructor(protected _renderer: Renderer2, protected _elementRef: ElementRef) { @@ -289,6 +310,7 @@ export class JigsawWarningAlert extends JigsawCommonAlert { @Component({ templateUrl: 'common-alert.html', selector: 'jigsaw-error-alert, j-error-alert', + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawErrorAlert extends JigsawCommonAlert { @@ -331,7 +353,8 @@ export class JigsawErrorAlert extends JigsawCommonAlert { @Component({ templateUrl: 'common-alert.html', - selector: 'jigsaw-confirm-alert, j-confirm-alert' + selector: 'jigsaw-confirm-alert, j-confirm-alert', + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawConfirmAlert extends JigsawCommonAlert { constructor(protected _renderer: Renderer2, protected _elementRef: ElementRef) { diff --git a/src/jigsaw/pc-components/cascade/cascade.ts b/src/jigsaw/pc-components/cascade/cascade.ts index 238b1301b4..dab9ff131c 100644 --- a/src/jigsaw/pc-components/cascade/cascade.ts +++ b/src/jigsaw/pc-components/cascade/cascade.ts @@ -1,9 +1,20 @@ import { - AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, NgModule, OnInit, Optional, Output, ViewChild, OnDestroy + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, Injector, + Input, + NgModule, + OnDestroy, + OnInit, + Optional, + Output, + ViewChild } from "@angular/core"; import {CommonModule} from "@angular/common"; import {TranslateModule, TranslateService} from "@ngx-translate/core"; -import {Observable} from "rxjs"; +import {Observable, Subscription} from "rxjs"; import {JigsawTabsModule} from "../tabs/index"; import {JigsawTileSelectModule} from "../list-and-tile/tile"; import {JigsawTab} from "../tabs/tab"; @@ -15,6 +26,7 @@ import {TranslateHelper} from "../../common/core/utils/translate-helper"; import {SimpleTreeData, TreeData} from "../../common/core/data/tree-data"; import {JigsawInputModule} from "../input/input"; import {JigsawPaginationModule} from "../pagination/pagination"; +import {RequireMarkForCheck} from "../../common/decorator/mark-for-check"; export class CascadeData { /** @@ -78,10 +90,13 @@ export class CascadeTabContentInitData { host: { '[class.jigsaw-cascade]': 'true', '[style.width]': 'width', - } + }, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawCascade extends AbstractJigsawComponent implements AfterViewInit, OnInit { - constructor(private _changeDetectorRef: ChangeDetectorRef) { + constructor(private _changeDetectorRef: ChangeDetectorRef, + // @RequireMarkForCheck 需要用到,勿删 + private _injector: Injector) { super(); } @@ -99,11 +114,10 @@ export class JigsawCascade extends AbstractJigsawComponent implements AfterViewI /** * 生成级联数据的函数,一般用于需要异步加载的数据的生产 * - * @NoMarkForCheckRequired - * * $demo = cascade/lazy-load * $demo = cascade/selected-items */ + @RequireMarkForCheck() @Input() public dataGenerator: CascadeDateGenerator; @@ -138,7 +152,7 @@ export class JigsawCascade extends AbstractJigsawComponent implements AfterViewI return this._data; } - public set data(value: CascadeDateGenerator | SimpleTreeData| TreeData) { + public set data(value: CascadeDateGenerator | SimpleTreeData | TreeData) { this._data = value; if (value instanceof Function) { this.dataGenerator = value; @@ -302,7 +316,7 @@ export class JigsawCascade extends AbstractJigsawComponent implements AfterViewI } else { this._selectedItems.splice(level, this.selectedItems.length - level, [...selectedItems]); } - + this._changeDetectorRef.markForCheck(); // 多选的tab是级联结束的地方,在这更新选中的数据 this.selectedItemsChange.emit(this._selectedItems); } @@ -318,6 +332,7 @@ export class JigsawCascade extends AbstractJigsawComponent implements AfterViewI } else { this._cascading(level + 1, selectedItem); } + this._changeDetectorRef.markForCheck(); } /** @@ -331,6 +346,7 @@ export class JigsawCascade extends AbstractJigsawComponent implements AfterViewI this._removeCascadingTabs(level); this._tabs.selectedIndex = this._tabs.length - 1; this._selectedItems = this._selectedItems.slice(0, level); + this._changeDetectorRef.markForCheck(); this.selectedItemsChange.emit(this._selectedItems); } @@ -429,7 +445,8 @@ export class JigsawCascade extends AbstractJigsawComponent implements AfterViewI (click)="_$cascade?._selectAll(initData.level)"> {{'cascade.all' | translate}} - + {{item && item[_$cascade?.labelField] ? item[_$cascade?.labelField] : item}} @@ -439,14 +456,19 @@ export class JigsawCascade extends AbstractJigsawComponent implements AfterViewI - ` + `, + changeDetection: ChangeDetectionStrategy.OnPush }) export class InternalTabContent extends AbstractJigsawComponent implements IDynamicInstantiatable, OnInit, OnDestroy { constructor( /** * @internal */ - @Optional() public _$cascade: JigsawCascade + @Optional() + public _$cascade: JigsawCascade, + private _cdr: ChangeDetectorRef, + // @RequireMarkForCheck 需要用到,勿删 + private _injector: Injector ) { super(); } @@ -482,28 +504,29 @@ export class InternalTabContent extends AbstractJigsawComponent implements IDyna /** * @internal */ + @RequireMarkForCheck() public get _$list() { return this._list; } public set _$list(value: any) { - if(!value || this._list == value) return; + if (!value || this._list == value) return; if (value instanceof LocalPageableArray && value.pagingInfo) { this._list = value; - if(this._removeListRefreshListener) { + if (this._removeListRefreshListener) { this._removeListRefreshListener(); this._removeListRefreshListener = null; } // 用于刷新分页 this._removeListRefreshListener = this._list.onRefresh(this._$updateCurrentPageSelectedItems, this); - } else if(value instanceof Array || value instanceof ArrayCollection) { + } else if (value instanceof Array || value instanceof ArrayCollection) { const data = new LocalPageableArray(); data.pagingInfo.pageSize = this._$cascade.pageSize; data.fromArray(value); const removeDataOnRefresh = data.onRefresh(() => { removeDataOnRefresh(); this._list = data; - if(this._removeListRefreshListener) { + if (this._removeListRefreshListener) { this._removeListRefreshListener(); this._removeListRefreshListener = null; } @@ -550,6 +573,8 @@ export class InternalTabContent extends AbstractJigsawComponent implements IDyna } } + private _removeFilterSubscribe: Subscription; + /** * @internal */ @@ -562,12 +587,15 @@ export class InternalTabContent extends AbstractJigsawComponent implements IDyna } filterKey = filterKey ? filterKey.trim() : ''; ( | PageableArray>this._$list).filter(filterKey, [this._$cascade.labelField]); + this._removeFilterSubscribe = ( | PageableArray>this._$list).pagingInfo.subscribe(() => { + this._cdr.markForCheck(); + }); } private _updateSelectedItemsByCurrent() { this._$currentPageSelectedItems = this._$currentPageSelectedItems ? this._$currentPageSelectedItems : []; this._$selectedItems = this._$selectedItems ? this._$selectedItems : []; - if(this.initData.multipleSelect) { + if (this.initData.multipleSelect) { this._$selectedItems.push(...this._$currentPageSelectedItems.filter(item => !this._$selectedItems.some(it => CommonUtils.compareWithKeyProperty(item, it, this._$cascade.trackItemBy)))); const currentUnselectedItems = this._$list.concat().filter(item => @@ -577,6 +605,7 @@ export class InternalTabContent extends AbstractJigsawComponent implements IDyna } else { this._$selectedItems = this._$currentPageSelectedItems; } + this._cdr.markForCheck(); } /** @@ -586,12 +615,13 @@ export class InternalTabContent extends AbstractJigsawComponent implements IDyna this.runMicrotask(() => { // 初始化时触发变更检查 this._$selectedItems = this._$selectedItems ? this._$selectedItems : []; - if(this._$list instanceof LocalPageableArray && this._$list.pagingInfo.pageSize != Infinity) { + if (this._$list instanceof LocalPageableArray && this._$list.pagingInfo.pageSize != Infinity) { this._$currentPageSelectedItems = this._$selectedItems.filter(item => (this._$list).some(it => CommonUtils.compareWithKeyProperty(it, item, this._$cascade.trackItemBy))); } else { this._$currentPageSelectedItems = this._$selectedItems; } + this._cdr.markForCheck(); }); } @@ -611,6 +641,7 @@ export class InternalTabContent extends AbstractJigsawComponent implements IDyna }); }) } + this._cdr.markForCheck(); } ngOnInit() { @@ -635,6 +666,7 @@ export class InternalTabContent extends AbstractJigsawComponent implements IDyna subscriber.unsubscribe(); this.callLater(() => { this._$showLoading = false; + this._cdr.markForCheck(); }, 300); }, () => subscriber.unsubscribe()); } else if (list instanceof Array) { @@ -643,10 +675,14 @@ export class InternalTabContent extends AbstractJigsawComponent implements IDyna } ngOnDestroy() { - if(this._removeListRefreshListener) { + if (this._removeListRefreshListener) { this._removeListRefreshListener(); this._removeListRefreshListener = null; } + if (this._removeFilterSubscribe) { + this._removeFilterSubscribe.unsubscribe(); + this._removeFilterSubscribe = null; + } } } diff --git a/src/jigsaw/pc-components/dialog/dialog.ts b/src/jigsaw/pc-components/dialog/dialog.ts index 0ddc4c681f..d217320474 100644 --- a/src/jigsaw/pc-components/dialog/dialog.ts +++ b/src/jigsaw/pc-components/dialog/dialog.ts @@ -1,11 +1,14 @@ import { AfterContentInit, AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, Component, ContentChildren, Directive, ElementRef, EventEmitter, + Injector, Input, NgModule, NgZone, @@ -22,6 +25,7 @@ import {JigsawButton, JigsawButtonModule} from "../button/button"; import {CommonUtils} from "../../common/core/utils/common-utils"; import {JigsawBlockModule} from "../../common/components/block/block"; import {JigsawMovableModule} from "../../common/directive/movable/index"; +import {RequireMarkForCheck} from "../../common/decorator/mark-for-check"; export interface IDialog extends IPopupable { buttons: ButtonInfo[]; @@ -114,20 +118,20 @@ export abstract class AbstractDialogComponentBase extends AbstractJigsawComponent implements IPopupable, AfterContentInit, OnDestroy { - constructor(protected renderer: Renderer2, protected elementRef: ElementRef, protected _zone: NgZone) { + constructor(protected renderer: Renderer2, protected elementRef: ElementRef, protected _zone: NgZone, + // @RequireMarkForCheck 需要用到,勿删 + protected _injector: Injector) { super(_zone); } - /** - * @NoMarkForCheckRequired - */ + @RequireMarkForCheck() @Input() public buttons: ButtonInfo[]; - /** - * @NoMarkForCheckRequired - */ + + @RequireMarkForCheck() @Input() public caption: string; + /** * @NoMarkForCheckRequired */ @@ -204,6 +208,7 @@ export abstract class AbstractDialogComponentBase @Component({ selector: 'jigsaw-dialog, j-dialog', templateUrl: 'dialog.html', + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawDialog extends AbstractDialogComponentBase implements AfterContentInit { @Output() @@ -224,8 +229,10 @@ export class JigsawDialog extends AbstractDialogComponentBase implements AfterCo */ public _$hasInlineButtons: boolean = false; - constructor(protected renderer: Renderer2, protected elementRef: ElementRef, protected _zone: NgZone) { - super(renderer, elementRef, _zone); + constructor(protected renderer: Renderer2, protected elementRef: ElementRef, protected _zone: NgZone, + // @RequireMarkForCheck 需要用到,勿删 + protected _injector: Injector) { + super(renderer, elementRef, _zone, _injector); this.renderer.addClass(this.elementRef.nativeElement, 'jigsaw-dialog-host'); } @@ -239,7 +246,6 @@ export class JigsawDialog extends AbstractDialogComponentBase implements AfterCo // 只有通过 "[jigsaw-button], [jigsaw-button-bar]" 投影进来的button,才算 button-group 里面的 return btn.element.nativeElement.hasAttribute('jigsaw-button') || (btn.element.nativeElement.parentElement && btn.element.nativeElement.parentElement.hasAttribute('jigsaw-button-bar')); - }); } } diff --git a/src/jigsaw/pc-components/list-and-tile/button-bar.ts b/src/jigsaw/pc-components/list-and-tile/button-bar.ts index cc0dbd48d1..2d83da3b84 100644 --- a/src/jigsaw/pc-components/list-and-tile/button-bar.ts +++ b/src/jigsaw/pc-components/list-and-tile/button-bar.ts @@ -1,4 +1,4 @@ -import {Component, NgModule, forwardRef, Input} from "@angular/core"; +import {Component, NgModule, forwardRef, Input, ChangeDetectionStrategy} from "@angular/core"; import {CommonModule} from "@angular/common"; import {JigsawTileSelectModule} from "./tile"; import {NG_VALUE_ACCESSOR} from "@angular/forms"; @@ -11,7 +11,7 @@ import {AbstractJigsawGroupLiteComponent} from "./group-lite-common"; [multipleSelect]="multipleSelect" [height]="height" [valid]="valid" (selectedItemsChange)="_$handleSelectChange($event)"> {{item && item[labelField] ? item[labelField] : item}} @@ -25,7 +25,8 @@ import {AbstractJigsawGroupLiteComponent} from "./group-lite-common"; }, providers: [ {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JigsawButtonBar), multi: true}, - ] + ], + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawButtonBar extends AbstractJigsawGroupLiteComponent { /** diff --git a/src/jigsaw/pc-components/list-and-tile/group-common.ts b/src/jigsaw/pc-components/list-and-tile/group-common.ts index b7f47b8617..0ee4e66890 100644 --- a/src/jigsaw/pc-components/list-and-tile/group-common.ts +++ b/src/jigsaw/pc-components/list-and-tile/group-common.ts @@ -1,9 +1,21 @@ import {AbstractJigsawComponent} from "../../common/common"; import {ControlValueAccessor} from "@angular/forms"; -import { AfterContentInit, ChangeDetectorRef, EventEmitter, Input, OnDestroy, Output, QueryList, OnInit, Directive } from "@angular/core"; +import { + AfterContentInit, + ChangeDetectorRef, + EventEmitter, + Input, + OnDestroy, + Output, + QueryList, + OnInit, + Directive, + Injector +} from "@angular/core"; import {CallbackRemoval, CommonUtils} from "../../common/core/utils/common-utils"; import {ArrayCollection} from "../../common/core/data/array-collection"; import {Subscription} from "rxjs"; +import {RequireMarkForCheck} from "../../common/decorator/mark-for-check"; export class GroupOptionValue { [index: string]: any; @@ -53,9 +65,7 @@ export class AbstractJigsawGroupComponent extends AbstractJigsawComponent implem protected _selectedItems = new ArrayCollection(); - /** - * @NoMarkForCheckRequired - */ + @RequireMarkForCheck() @Input() public get selectedItems(): ArrayCollection | any[] { return this._selectedItems; @@ -69,10 +79,17 @@ export class AbstractJigsawGroupComponent extends AbstractJigsawComponent implem this._propagateChange(newValue); } + constructor(protected _cdr: ChangeDetectorRef, + // @RequireMarkForCheck 需要用到,勿删 + private _injector: Injector) { + super(); + } + /** * @internal */ public _removeInvalidSelectedItems(): void { + this._cdr.markForCheck(); if (!this._items || !this._selectedItems || !this._selectedItems.length) { return; } @@ -85,7 +102,7 @@ export class AbstractJigsawGroupComponent extends AbstractJigsawComponent implem this._selectedItems.splice(this.selectedItems.indexOf(selectedItem), 1); needRefresh = true; }); - if(needRefresh) { + if (needRefresh) { this.selectedItemsChange.emit(this.selectedItems); } } @@ -230,24 +247,25 @@ export class AbstractJigsawGroupComponent extends AbstractJigsawComponent implem @Directive() export class AbstractJigsawOptionComponent extends AbstractJigsawComponent { - /** - * @NoMarkForCheckRequired - */ + + constructor( + // @RequireMarkForCheck 需要用到,勿删 + protected _injector: Injector) { + super(); + } + + @RequireMarkForCheck() @Input() public value: any; - /** - * @NoMarkForCheckRequired - */ + @RequireMarkForCheck() @Input() public disabled: boolean = false; @Output() public selectedChange = new EventEmitter(); - /** - * @NoMarkForCheckRequired - */ + @RequireMarkForCheck() @Input() public selected: boolean = false; // 选中状态 @@ -255,5 +273,4 @@ export class AbstractJigsawOptionComponent extends AbstractJigsawComponent { public change = new EventEmitter(); public changeDetector: ChangeDetectorRef - } diff --git a/src/jigsaw/pc-components/list-and-tile/list-lite.ts b/src/jigsaw/pc-components/list-and-tile/list-lite.ts index d6e0f35d77..cf536091b2 100644 --- a/src/jigsaw/pc-components/list-and-tile/list-lite.ts +++ b/src/jigsaw/pc-components/list-and-tile/list-lite.ts @@ -1,14 +1,15 @@ import { AfterViewInit, ChangeDetectorRef, Component, forwardRef, Input, NgModule, QueryList, ViewChild, - ViewChildren, OnDestroy, Output, EventEmitter, NgZone + ViewChildren, OnDestroy, Output, EventEmitter, NgZone, ChangeDetectionStrategy } from "@angular/core"; -import {ArrayCollection, LocalPageableArray, PageableArray} from "../../common/core/data/array-collection"; import {CommonModule} from "@angular/common"; +import {NG_VALUE_ACCESSOR} from "@angular/forms"; +import {Subscription} from "rxjs"; +import {PerfectScrollbarDirective, PerfectScrollbarModule} from "ngx-perfect-scrollbar"; +import {ArrayCollection, LocalPageableArray, PageableArray} from "../../common/core/data/array-collection"; import {JigsawList, JigsawListModule, JigsawListOption} from "./list"; import {JigsawInputModule} from "../input/input"; import {GroupOptionValue} from "./group-common"; -import {PerfectScrollbarDirective, PerfectScrollbarModule} from "ngx-perfect-scrollbar"; -import {NG_VALUE_ACCESSOR} from "@angular/forms"; import {AbstractJigsawGroupLiteComponent} from "./group-lite-common"; import {CallbackRemoval} from "../../common/core/utils/common-utils"; @@ -20,20 +21,22 @@ import {CallbackRemoval} from "../../common/core/utils/common-utils"; * - 支持搜索功能 * - 支持文本溢出显示省略号,鼠标移入会有提示信息 * - 可以和combo结合起来使用 - * */ // @dynamic @Component({ selector: 'jigsaw-list-lite, j-list-lite', template: ` - + -
- +

{{item && item[labelField] ? item[labelField] : item}}

@@ -47,7 +50,8 @@ import {CallbackRemoval} from "../../common/core/utils/common-utils"; }, providers: [ {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JigsawListLite), multi: true}, - ] + ], + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawListLite extends AbstractJigsawGroupLiteComponent implements AfterViewInit, OnDestroy { constructor(private _changeDetectorRef: ChangeDetectorRef, protected _zone: NgZone) { @@ -79,18 +83,18 @@ export class JigsawListLite extends AbstractJigsawGroupLiteComponent implements } public set data(data: ArrayCollection | LocalPageableArray | PageableArray | GroupOptionValue[]) { - if(!data || this.data == data) return; + if (!data || this.data == data) return; this._data = data; this.dataChange.emit(this.data); - if(this._data instanceof ArrayCollection || this._data instanceof LocalPageableArray || this._data instanceof PageableArray) { - if(this._removeOnChange) { + if (this._data instanceof ArrayCollection || this._data instanceof LocalPageableArray || this._data instanceof PageableArray) { + if (this._removeOnChange) { this._removeOnChange(); } this._removeOnChange = this._data.onChange(() => { this.removeInvalidSelectedItems(); }); } - if(this._needCheckSelectedItems) { + if (this._needCheckSelectedItems) { this.removeInvalidSelectedItems(); } else { this._needCheckSelectedItems = true; @@ -136,7 +140,7 @@ export class JigsawListLite extends AbstractJigsawGroupLiteComponent implements private _needCheckSelectedItems: boolean = true; public removeInvalidSelectedItems() { - if(this._listInst) { + if (this._listInst) { // 等待ngFor渲染 this.runAfterMicrotasks(() => { this._zone.run(() => { @@ -146,6 +150,8 @@ export class JigsawListLite extends AbstractJigsawGroupLiteComponent implements } } + private _removeFilterSubscribe: Subscription; + /** * @internal */ @@ -159,9 +165,13 @@ export class JigsawListLite extends AbstractJigsawGroupLiteComponent implements } filterKey = filterKey ? filterKey.trim() : ''; ( | PageableArray>this.data).filter(filterKey, [this.labelField]); + this._removeFilterSubscribe = ( | PageableArray>this.data).pagingInfo.subscribe(() => { + this._changeDetectorRef.markForCheck(); + }); this._listScrollbar && this._listScrollbar.scrollToTop(); } + private _setListWrapperHeight() { if (!this.optionCount || !this._listOptions.length) return; this.height = this._listOptions.first.elementRef.nativeElement.offsetHeight * this.optionCount + 'px'; @@ -177,10 +187,14 @@ export class JigsawListLite extends AbstractJigsawGroupLiteComponent implements ngOnDestroy() { super.ngOnDestroy(); - if(this._removeOnChange) { + if (this._removeOnChange) { this._removeOnChange(); this._removeOnChange = null; } + if (this._removeFilterSubscribe) { + this._removeFilterSubscribe.unsubscribe(); + this._removeFilterSubscribe = null; + } } } diff --git a/src/jigsaw/pc-components/list-and-tile/list.ts b/src/jigsaw/pc-components/list-and-tile/list.ts index 57228309fd..516de81e82 100644 --- a/src/jigsaw/pc-components/list-and-tile/list.ts +++ b/src/jigsaw/pc-components/list-and-tile/list.ts @@ -1,11 +1,20 @@ import { - AfterContentInit, ChangeDetectorRef, Component, ContentChildren, ElementRef, forwardRef, Input, NgModule, + AfterContentInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ContentChildren, + ElementRef, + forwardRef, Injector, + Input, + NgModule, QueryList } from "@angular/core"; import {CommonModule} from "@angular/common"; import {FormsModule, NG_VALUE_ACCESSOR} from "@angular/forms"; import {AbstractJigsawOptionComponent} from "./group-common"; import {AbstractJigsawGroupComponent} from "./group-common"; +import {RequireMarkForCheck} from "../../common/decorator/mark-for-check"; @Component({ selector: 'jigsaw-list, j-list', @@ -18,7 +27,8 @@ import {AbstractJigsawGroupComponent} from "./group-common"; }, providers: [ {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JigsawList), multi: true}, - ] + ], + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawList extends AbstractJigsawGroupComponent implements AfterContentInit { /** @@ -30,7 +40,7 @@ export class JigsawList extends AbstractJigsawGroupComponent implements AfterCon * @NoMarkForCheckRequired */ @Input() - public disabled : boolean =false; + public disabled: boolean = false; /** * 获取映射的子组件 @@ -49,18 +59,19 @@ export class JigsawList extends AbstractJigsawGroupComponent implements AfterCon '[class.jigsaw-list-option-disabled]': 'disabled', '[class.jigsaw-list-option-separator]': '!value', '(click)': '_$handleClick()' - } + }, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawListOption extends AbstractJigsawOptionComponent { - constructor(public changeDetector: ChangeDetectorRef, public elementRef: ElementRef) { - super(); + constructor(public elementRef: ElementRef, + // @RequireMarkForCheck 需要用到,勿删 + protected _injector: Injector) { + super(_injector); } private _selected: boolean = false; // 选中状态 - /** - * @NoMarkForCheckRequired - */ + @RequireMarkForCheck() @Input() public get selected(): boolean { return this._selected; @@ -79,7 +90,7 @@ export class JigsawListOption extends AbstractJigsawOptionComponent { * @internal */ public _$handleClick(): void { - if(this.disabled || !this.value) return; + if (this.disabled || !this.value) return; this.change.emit(this); } } diff --git a/src/jigsaw/pc-components/list-and-tile/tile-lite.ts b/src/jigsaw/pc-components/list-and-tile/tile-lite.ts index aa800147b5..bf9c7ad139 100644 --- a/src/jigsaw/pc-components/list-and-tile/tile-lite.ts +++ b/src/jigsaw/pc-components/list-and-tile/tile-lite.ts @@ -1,4 +1,4 @@ -import {Component, NgModule, forwardRef, Input} from "@angular/core"; +import {Component, NgModule, forwardRef, Input, ChangeDetectionStrategy, ChangeDetectorRef} from "@angular/core"; import {CommonModule} from "@angular/common"; import {JigsawTileSelectModule} from "./tile"; import {NG_VALUE_ACCESSOR} from "@angular/forms"; @@ -24,7 +24,8 @@ import {AbstractJigsawGroupLiteComponent} from "./group-lite-common"; }, providers: [ {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JigsawTileLite), multi: true}, - ] + ], + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawTileLite extends AbstractJigsawGroupLiteComponent { /** diff --git a/src/jigsaw/pc-components/list-and-tile/tile.ts b/src/jigsaw/pc-components/list-and-tile/tile.ts index 1907921cce..4c394e4d7b 100644 --- a/src/jigsaw/pc-components/list-and-tile/tile.ts +++ b/src/jigsaw/pc-components/list-and-tile/tile.ts @@ -1,8 +1,19 @@ -import {ChangeDetectorRef, Component, ContentChildren, forwardRef, Input, NgModule, QueryList,} from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ContentChildren, ElementRef, + forwardRef, Injector, + Input, + NgModule, + QueryList, +} from '@angular/core'; import {CommonModule} from '@angular/common'; import {FormsModule, NG_VALUE_ACCESSOR} from '@angular/forms' import {JigsawInputModule} from '../input/input'; import {AbstractJigsawGroupComponent, AbstractJigsawOptionComponent} from "./group-common"; +import {ArrayCollection} from "../../common/core/data/array-collection"; +import {RequireMarkForCheck} from "../../common/decorator/mark-for-check"; @Component({ selector: 'jigsaw-tile, j-tile', @@ -16,7 +27,8 @@ import {AbstractJigsawGroupComponent, AbstractJigsawOptionComponent} from "./gro }, providers: [ {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JigsawTile), multi: true}, - ] + ], + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawTile extends AbstractJigsawGroupComponent { // 默认多选 @@ -30,7 +42,6 @@ export class JigsawTile extends AbstractJigsawGroupComponent { */ @Input() public showBorder: boolean = true; - } @Component({ @@ -44,12 +55,14 @@ export class JigsawTile extends AbstractJigsawGroupComponent { '[class.jigsaw-tile-option-active]': 'selected', '[class.jigsaw-tile-option-disabled]': 'disabled', '(click)': '_$handleClick()' - } + }, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawTileOption extends AbstractJigsawOptionComponent { - constructor(public changeDetector: ChangeDetectorRef) { - super(); + constructor(// @RequireMarkForCheck 需要用到,勿删 + protected _injector: Injector) { + super(_injector); } /** diff --git a/src/jigsaw/pc-components/menu/menu.ts b/src/jigsaw/pc-components/menu/menu.ts index 27eaaa7ddd..f5ad4621ca 100644 --- a/src/jigsaw/pc-components/menu/menu.ts +++ b/src/jigsaw/pc-components/menu/menu.ts @@ -1,16 +1,17 @@ import { + AfterContentInit, + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, Component, - Output, + ElementRef, EventEmitter, Input, - ViewChild, - ElementRef, + Output, Renderer2, - AfterViewInit, - AfterContentInit, - ChangeDetectorRef + ViewChild } from "@angular/core"; -import {IPopupable, PopupOptions, PopupService, PopupInfo, PopupPositionType} from "../../common/service/popup.service"; +import {IPopupable, PopupInfo, PopupOptions, PopupPositionType, PopupService} from "../../common/service/popup.service"; import {SimpleNode, SimpleTreeData} from "../../common/core/data/tree-data"; import {AbstractJigsawComponent} from "../../common/common"; import {CommonUtils} from '../../common/core/utils/common-utils'; @@ -61,7 +62,8 @@ export function closeAllContextMenu(popups: PopupInfo[]): void { (jigsawCascadingMenuSelect)="onSelect($event)" (jigsawCascadingMenuClose)="close.emit()">
- ` + `, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawMenuHelper implements IPopupable { public answer: EventEmitter = new EventEmitter(); @@ -127,7 +129,8 @@ export class JigsawMenuHelper implements IPopupable { '[class.jigsaw-menu-light]': "_$realTheme == 'light'", '[class.jigsaw-menu-black]': "_$realTheme == 'black'", '[class.jigsaw-menu-navigation]': "_$realTheme == 'navigation'", - } + }, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawMenu extends AbstractJigsawComponent implements IPopupable, AfterViewInit, AfterContentInit { @@ -317,7 +320,7 @@ export class JigsawMenu extends AbstractJigsawComponent implements IPopupable, A const listOptionElements = this._menuListElement.nativeElement.children; const titleElement = listOptionElements[index].getElementsByClassName("menu-list-title")[0]; if (!titleElement) { - return {maxWidth: 'auto'} ; + return {maxWidth: 'auto'}; } const wrapElement = titleElement.parentElement; // 5是给有子节点时,留下的箭头; diff --git a/src/jigsaw/pc-components/notification/notification.ts b/src/jigsaw/pc-components/notification/notification.ts index 6b89a04235..beac92f572 100644 --- a/src/jigsaw/pc-components/notification/notification.ts +++ b/src/jigsaw/pc-components/notification/notification.ts @@ -1,5 +1,5 @@ import { - NgModule, Component, Renderer2, Input, ElementRef, NgZone,ChangeDetectionStrategy + NgModule, Component, Renderer2, Input, ElementRef, NgZone, ChangeDetectionStrategy, Injector } from "@angular/core"; import {CommonModule} from "@angular/common"; import {AbstractDialogComponentBase, DialogCallback} from "../dialog/dialog"; @@ -114,8 +114,10 @@ const notificationInstances = { changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawNotification extends AbstractDialogComponentBase { - constructor(protected renderer: Renderer2, protected elementRef: ElementRef, protected _zone: NgZone) { - super(renderer, elementRef, _zone); + constructor(protected renderer: Renderer2, protected elementRef: ElementRef, protected _zone: NgZone, + // @RequireMarkForCheck 需要用到,勿删 + protected _injector: Injector) { + super(renderer, elementRef, _zone, _injector); } protected getPopupElement(): HTMLElement { diff --git a/src/jigsaw/pc-components/radio/radio-lite.ts b/src/jigsaw/pc-components/radio/radio-lite.ts index 4ecf517548..b1a90909af 100644 --- a/src/jigsaw/pc-components/radio/radio-lite.ts +++ b/src/jigsaw/pc-components/radio/radio-lite.ts @@ -1,4 +1,13 @@ -import {Component, EventEmitter, forwardRef, Input, NgModule, Output} from "@angular/core"; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + forwardRef, + Input, + NgModule, + Output +} from "@angular/core"; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms"; import {CommonModule} from "@angular/common"; import {JigsawRadioModule} from "./radio"; @@ -21,7 +30,8 @@ import {CommonUtils} from "../../common/core/utils/common-utils"; }, providers: [ {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JigsawRadiosLite), multi: true}, - ] + ], + changeDetection:ChangeDetectionStrategy.OnPush }) export class JigsawRadiosLite extends AbstractJigsawComponent implements ControlValueAccessor { diff --git a/src/jigsaw/pc-components/radio/radio.ts b/src/jigsaw/pc-components/radio/radio.ts index c15f0be7f6..0409ab3924 100644 --- a/src/jigsaw/pc-components/radio/radio.ts +++ b/src/jigsaw/pc-components/radio/radio.ts @@ -1,8 +1,10 @@ import { + ChangeDetectionStrategy, ChangeDetectorRef, - Component, ContentChildren, + Component, + ContentChildren, EventEmitter, - forwardRef, + forwardRef, Injector, Input, NgModule, Output, @@ -23,7 +25,8 @@ import {CommonUtils} from "../../common/core/utils/common-utils"; }, providers: [ {provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JigsawRadioGroup), multi: true}, - ] + ], + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawRadioGroup extends AbstractJigsawGroupComponent { @@ -85,11 +88,13 @@ export class JigsawRadioGroup extends AbstractJigsawGroupComponent { '(click)': '_$handleClick()', '[class.jigsaw-radio-option]': 'true', '[class.jigsaw-radio-option-disabled]': 'disabled' - } + }, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawRadioOption extends AbstractJigsawOptionComponent { - constructor(public changeDetector: ChangeDetectorRef) { - super(); + constructor(// @RequireMarkForCheck 需要用到,勿删 + protected _injector: Injector) { + super(_injector); } /** diff --git a/src/jigsaw/pc-components/root/root.ts b/src/jigsaw/pc-components/root/root.ts index f5212af47e..e874744b36 100644 --- a/src/jigsaw/pc-components/root/root.ts +++ b/src/jigsaw/pc-components/root/root.ts @@ -1,14 +1,23 @@ -import {Component, Injector, NgModule, NgZone, Renderer2, ViewContainerRef} from "@angular/core"; +import { + ChangeDetectionStrategy, + Injector, + Component, + NgModule, + NgZone, + Renderer2, + ViewContainerRef +} from "@angular/core"; import {PopupService} from "../../common/service/popup.service"; import {InternalUtils} from "../../common/core/utils/internal-utils"; @Component({ selector: 'jigsaw-root, j-root', - template: '' + template: '', + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawRoot { constructor(viewContainerRef: ViewContainerRef, renderer: Renderer2, zone: NgZone, injector: Injector, - ps:PopupService /* do not remove this line, need for global PopupService instantiate! */) { + ps: PopupService /* do not remove this line, need for global PopupService instantiate! */) { InternalUtils.viewContainerRef = viewContainerRef; InternalUtils.renderer = renderer; InternalUtils.zone = zone; diff --git a/src/jigsaw/pc-components/tabs/tab-item.ts b/src/jigsaw/pc-components/tabs/tab-item.ts index 18ceec8614..2e13e995f3 100644 --- a/src/jigsaw/pc-components/tabs/tab-item.ts +++ b/src/jigsaw/pc-components/tabs/tab-item.ts @@ -163,7 +163,8 @@ export class JigsawTabLabel extends JigsawTabBase implements AfterViewInit { }, template: ` - ` + `, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawTabContent extends JigsawTabBase implements AfterViewInit { diff --git a/src/jigsaw/pc-components/transfer/transfer.ts b/src/jigsaw/pc-components/transfer/transfer.ts index 7a7919c903..d581431a7d 100644 --- a/src/jigsaw/pc-components/transfer/transfer.ts +++ b/src/jigsaw/pc-components/transfer/transfer.ts @@ -1,6 +1,15 @@ -import {Component, Input, NgModule, OnDestroy, Optional, ChangeDetectorRef} from "@angular/core"; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + Input, + NgModule, + OnDestroy, + Optional, + ViewChild +} from "@angular/core"; import {CommonModule} from "@angular/common"; -import {trigger, style, transition, animate, keyframes} from "@angular/animations" +import {animate, keyframes, style, transition, trigger} from "@angular/animations" import {Subscription} from "rxjs/internal/Subscription"; import {TranslateModule, TranslateService} from "@ngx-translate/core"; import {PerfectScrollbarModule} from "ngx-perfect-scrollbar"; @@ -16,7 +25,6 @@ import {InternalUtils} from "../../common/core/utils/internal-utils"; import {LoadingService} from "../../common/service/loading.service"; import {TranslateHelper} from "../../common/core/utils/translate-helper"; - // 此处不能使用箭头函数 const transferFilterFunction = function (item) { let listResult = true; @@ -108,7 +116,8 @@ const transferServerFilterFunction = function (item) { style({opacity: 0}) ])) ]) - ])] + ])], + changeDetection: ChangeDetectionStrategy.OnPush }) @@ -254,7 +263,10 @@ export class JigsawTransfer extends AbstractJigsawGroupLiteComponent implements } private _filterData() { - this._$data.filter(this._filterFunction, {selectedItems: [].concat(...this.selectedItems), trackItemBy: this.trackItemBy}); + this._$data.filter(this._filterFunction, { + selectedItems: [].concat(...this.selectedItems), + trackItemBy: this.trackItemBy + }); } /** @@ -311,7 +323,8 @@ export class JigsawTransfer extends AbstractJigsawGroupLiteComponent implements templateUrl: './transfer-list.html', host: { '[class.jigsaw-transfer-list-frame]': 'true' - } + }, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawTransferInternalList extends AbstractJigsawGroupLiteComponent implements OnDestroy { constructor(@Optional() private _transfer: JigsawTransfer, private _cdr: ChangeDetectorRef) { @@ -352,6 +365,7 @@ export class JigsawTransferInternalList extends AbstractJigsawGroupLiteComponent this.selectedItems = this.selectedItems.concat(); this._$updateCurrentPageSelectedItems(); } + this._cdr.markForCheck(); }); this._filterFunction = value instanceof LocalPageableArray ? transferFilterFunction : transferServerFilterFunction; } else if (value instanceof Array || value instanceof ArrayCollection) { @@ -459,6 +473,8 @@ export class JigsawTransferInternalList extends AbstractJigsawGroupLiteComponent } } + private _removeFilterSubscribe: Subscription; + private _filterData(filterKey: string, field: string | number) { this._data.filter(this._filterFunction, { selectedItems: this.isTarget ? null : [].concat(...this._transfer.selectedItems), @@ -466,7 +482,9 @@ export class JigsawTransferInternalList extends AbstractJigsawGroupLiteComponent keyword: filterKey, fields: [field] }); - this._cdr.detectChanges(); + this._removeFilterSubscribe = this._data.pagingInfo.subscribe(() => { + this._cdr.markForCheck(); + }); } /** @@ -488,6 +506,7 @@ export class JigsawTransferInternalList extends AbstractJigsawGroupLiteComponent !item.disabled && !(this.data).some(it => CommonUtils.compareWithKeyProperty(it, item, this.trackItemBy))) } this.selectedItemsChange.emit(this.selectedItems); + this._cdr.markForCheck(); } /** @@ -530,6 +549,10 @@ export class JigsawTransferInternalList extends AbstractJigsawGroupLiteComponent this._removeArrayCallbackListener(); this._removeArrayCallbackListener = null; } + if (this._removeFilterSubscribe) { + this._removeFilterSubscribe.unsubscribe(); + this._removeFilterSubscribe = null; + } } } diff --git a/src/jigsaw/pc-components/upload/upload.ts b/src/jigsaw/pc-components/upload/upload.ts index 03950f84dc..f695fcc094 100644 --- a/src/jigsaw/pc-components/upload/upload.ts +++ b/src/jigsaw/pc-components/upload/upload.ts @@ -1,5 +1,5 @@ import { - AfterViewInit, + AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Optional, @@ -16,7 +16,8 @@ import {TranslateService} from "@ngx-translate/core"; templateUrl: 'upload.html', host: { '[class.jigsaw-upload]': 'true' - } + }, + changeDetection: ChangeDetectionStrategy.OnPush }) export class JigsawUpload extends JigsawUploadBase implements AfterViewInit {