[ADF-1583] Fix change detection error (the quick way) (#2396)

* Fix change detection error (the quick way)

* Fix it the second time
This commit is contained in:
Popovics András 2017-09-29 17:49:01 +01:00 committed by Eugenio Romano
parent cf0b45acb6
commit 9f0e40a6e8
5 changed files with 40 additions and 21 deletions

View File

@ -4,7 +4,7 @@
</adf-sites-dropdown> </adf-sites-dropdown>
</div> </div>
<adf-upload-drag-area <adf-upload-drag-area
[parentId]="documentList.currentFolderId" [parentId]="getDocumentListCurrentFolderId()"
[versioning]="versioning" [versioning]="versioning"
[adf-node-permission]="'create'" [adf-node-permission]="'create'"
[adf-nodes]="getCurrentDocumentListNode()"> [adf-nodes]="getCurrentDocumentListNode()">

View File

@ -29,6 +29,8 @@ import { DocumentListComponent, PermissionStyleModel } from 'ng2-alfresco-docume
import { ViewerService } from 'ng2-alfresco-viewer'; import { ViewerService } from 'ng2-alfresco-viewer';
const DEFAULT_FOLDER_TO_SHOW = '-my-';
@Component({ @Component({
selector: 'adf-files-component', selector: 'adf-files-component',
templateUrl: './files.component.html', templateUrl: './files.component.html',
@ -36,7 +38,7 @@ import { ViewerService } from 'ng2-alfresco-viewer';
}) })
export class FilesComponent implements OnInit { export class FilesComponent implements OnInit {
// The identifier of a node. You can also use one of these well-known aliases: -my- | -shared- | -root- // The identifier of a node. You can also use one of these well-known aliases: -my- | -shared- | -root-
currentFolderId: string = '-my-'; currentFolderId: string = DEFAULT_FOLDER_TO_SHOW;
errorMessage: string = null; errorMessage: string = null;
fileNodeId: any; fileNodeId: any;
@ -114,6 +116,7 @@ export class FilesComponent implements OnInit {
} }
onFolderChange($event) { onFolderChange($event) {
this.currentFolderId = $event.value.id;
this.router.navigate(['/files', $event.value.id]); this.router.navigate(['/files', $event.value.id]);
} }
@ -220,7 +223,11 @@ export class FilesComponent implements OnInit {
} }
getSiteContent(site: SiteModel) { getSiteContent(site: SiteModel) {
this.currentFolderId = site && site.guid ? site.guid : '-my-'; this.currentFolderId = site && site.guid ? site.guid : DEFAULT_FOLDER_TO_SHOW;
}
getDocumentListCurrentFolderId() {
return this.documentList.currentFolderId || DEFAULT_FOLDER_TO_SHOW;
} }
hasSelection(selection: Array<MinimalNodeEntity>): boolean { hasSelection(selection: Array<MinimalNodeEntity>): boolean {

View File

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { DebugElement } from '@angular/core'; import { DebugElement } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MaterialModule } from '../../material.module'; import { MaterialModule } from '../../material.module';

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, ElementRef, SimpleChange } from '@angular/core'; import { ChangeDetectorRef, Component, ElementRef, SimpleChange } from '@angular/core';
import { AlfrescoContentService } from './../services/alfresco-content.service'; import { AlfrescoContentService } from './../services/alfresco-content.service';
import { NodePermissionDirective, NodePermissionSubject } from './node-permission.directive'; import { NodePermissionDirective, NodePermissionSubject } from './node-permission.directive';
@ -28,19 +28,27 @@ class TestComponent implements NodePermissionSubject {
describe('NodePermissionDirective', () => { describe('NodePermissionDirective', () => {
let changeDetectorMock: ChangeDetectorRef;
beforeEach(() => {
changeDetectorMock = <ChangeDetectorRef> { detectChanges: () => {} };
});
describe('HTML nativeElement as subject', () => { describe('HTML nativeElement as subject', () => {
it('updates element once it is loaded', () => { it('updates element once it is loaded', () => {
const directive = new NodePermissionDirective(null, null, null); const directive = new NodePermissionDirective(null, null, null, changeDetectorMock);
spyOn(directive, 'updateElement').and.stub(); spyOn(directive, 'updateElement').and.stub();
directive.ngAfterViewInit(); const nodes = [{}, {}];
const change = new SimpleChange([], nodes, false);
directive.ngOnChanges({ nodes: change });
expect(directive.updateElement).toHaveBeenCalled(); expect(directive.updateElement).toHaveBeenCalled();
}); });
it('updates element on nodes change', () => { it('updates element on nodes change', () => {
const directive = new NodePermissionDirective(null, null, null); const directive = new NodePermissionDirective(null, null, null, changeDetectorMock);
spyOn(directive, 'updateElement').and.stub(); spyOn(directive, 'updateElement').and.stub();
const nodes = [{}, {}]; const nodes = [{}, {}];
@ -51,7 +59,7 @@ describe('NodePermissionDirective', () => {
}); });
it('updates element only on subsequent change', () => { it('updates element only on subsequent change', () => {
const directive = new NodePermissionDirective(null, null, null); const directive = new NodePermissionDirective(null, null, null, changeDetectorMock);
spyOn(directive, 'updateElement').and.stub(); spyOn(directive, 'updateElement').and.stub();
const nodes = [{}, {}]; const nodes = [{}, {}];
@ -64,7 +72,7 @@ describe('NodePermissionDirective', () => {
it('enables decorated element', () => { it('enables decorated element', () => {
const renderer = jasmine.createSpyObj('renderer', ['removeAttribute']); const renderer = jasmine.createSpyObj('renderer', ['removeAttribute']);
const elementRef = new ElementRef({}); const elementRef = new ElementRef({});
const directive = new NodePermissionDirective(elementRef, renderer, null); const directive = new NodePermissionDirective(elementRef, renderer, null, changeDetectorMock);
directive.enableElement(); directive.enableElement();
@ -74,7 +82,7 @@ describe('NodePermissionDirective', () => {
it('disables decorated element', () => { it('disables decorated element', () => {
const renderer = jasmine.createSpyObj('renderer', ['setAttribute']); const renderer = jasmine.createSpyObj('renderer', ['setAttribute']);
const elementRef = new ElementRef({}); const elementRef = new ElementRef({});
const directive = new NodePermissionDirective(elementRef, renderer, null); const directive = new NodePermissionDirective(elementRef, renderer, null, changeDetectorMock);
directive.disableElement(); directive.disableElement();
@ -82,7 +90,7 @@ describe('NodePermissionDirective', () => {
}); });
it('disables element when nodes not available', () => { it('disables element when nodes not available', () => {
const directive = new NodePermissionDirective(null, null, null); const directive = new NodePermissionDirective(null, null, null, changeDetectorMock);
spyOn(directive, 'disableElement').and.stub(); spyOn(directive, 'disableElement').and.stub();
directive.nodes = null; directive.nodes = null;
@ -96,7 +104,7 @@ describe('NodePermissionDirective', () => {
const contentService = new AlfrescoContentService(null, null, null); const contentService = new AlfrescoContentService(null, null, null);
spyOn(contentService, 'hasPermission').and.returnValue(true); spyOn(contentService, 'hasPermission').and.returnValue(true);
const directive = new NodePermissionDirective(null, null, contentService); const directive = new NodePermissionDirective(null, null, contentService, changeDetectorMock);
spyOn(directive, 'enableElement').and.stub(); spyOn(directive, 'enableElement').and.stub();
directive.nodes = <any> [{}, {}]; directive.nodes = <any> [{}, {}];
@ -109,7 +117,7 @@ describe('NodePermissionDirective', () => {
const contentService = new AlfrescoContentService(null, null, null); const contentService = new AlfrescoContentService(null, null, null);
spyOn(contentService, 'hasPermission').and.returnValue(false); spyOn(contentService, 'hasPermission').and.returnValue(false);
const directive = new NodePermissionDirective(null, null, contentService); const directive = new NodePermissionDirective(null, null, contentService, changeDetectorMock);
spyOn(directive, 'disableElement').and.stub(); spyOn(directive, 'disableElement').and.stub();
directive.nodes = <any> [{}, {}]; directive.nodes = <any> [{}, {}];
@ -124,29 +132,33 @@ describe('NodePermissionDirective', () => {
it('disables decorated component', () => { it('disables decorated component', () => {
const contentService = new AlfrescoContentService(null, null, null); const contentService = new AlfrescoContentService(null, null, null);
spyOn(contentService, 'hasPermission').and.returnValue(false); spyOn(contentService, 'hasPermission').and.returnValue(false);
spyOn(changeDetectorMock, 'detectChanges');
let testComponent = new TestComponent(); let testComponent = new TestComponent();
testComponent.disabled = false; testComponent.disabled = false;
const directive = new NodePermissionDirective(null, null, contentService, testComponent); const directive = new NodePermissionDirective(null, null, contentService, changeDetectorMock, testComponent);
directive.nodes = <any> [{}, {}]; directive.nodes = <any> [{}, {}];
directive.updateElement(); directive.updateElement();
expect(testComponent.disabled).toBeTruthy(); expect(testComponent.disabled).toBeTruthy();
expect(changeDetectorMock.detectChanges).toHaveBeenCalledTimes(1);
}); });
it('enables decorated component', () => { it('enables decorated component', () => {
const contentService = new AlfrescoContentService(null, null, null); const contentService = new AlfrescoContentService(null, null, null);
spyOn(contentService, 'hasPermission').and.returnValue(true); spyOn(contentService, 'hasPermission').and.returnValue(true);
spyOn(changeDetectorMock, 'detectChanges');
let testComponent = new TestComponent(); let testComponent = new TestComponent();
testComponent.disabled = true; testComponent.disabled = true;
const directive = new NodePermissionDirective(null, null, contentService, testComponent); const directive = new NodePermissionDirective(null, null, contentService, changeDetectorMock, testComponent);
directive.nodes = <any> [{}, {}]; directive.nodes = <any> [{}, {}];
directive.updateElement(); directive.updateElement();
expect(testComponent.disabled).toBeFalsy(); expect(testComponent.disabled).toBeFalsy();
expect(changeDetectorMock.detectChanges).toHaveBeenCalledTimes(1);
}); });
}); });
}); });

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { AfterViewInit, Directive, ElementRef, Host, Inject, Input, OnChanges, Optional, Renderer2, SimpleChanges } from '@angular/core'; import { ChangeDetectorRef, Directive, ElementRef, Host, Inject, Input, OnChanges, Optional, Renderer2, SimpleChanges } from '@angular/core';
import { MinimalNodeEntity } from 'alfresco-js-api'; import { MinimalNodeEntity } from 'alfresco-js-api';
import { EXTENDIBLE_COMPONENT } from './../interface/injection.tokens'; import { EXTENDIBLE_COMPONENT } from './../interface/injection.tokens';
import { AlfrescoContentService } from './../services/alfresco-content.service'; import { AlfrescoContentService } from './../services/alfresco-content.service';
@ -27,7 +27,7 @@ export interface NodePermissionSubject {
@Directive({ @Directive({
selector: '[adf-node-permission]' selector: '[adf-node-permission]'
}) })
export class NodePermissionDirective implements OnChanges, AfterViewInit { export class NodePermissionDirective implements OnChanges {
@Input('adf-node-permission') @Input('adf-node-permission')
permission: string = null; permission: string = null;
@ -38,16 +38,13 @@ export class NodePermissionDirective implements OnChanges, AfterViewInit {
constructor(private elementRef: ElementRef, constructor(private elementRef: ElementRef,
private renderer: Renderer2, private renderer: Renderer2,
private contentService: AlfrescoContentService, private contentService: AlfrescoContentService,
private changeDetector: ChangeDetectorRef,
@Host() @Host()
@Optional() @Optional()
@Inject(EXTENDIBLE_COMPONENT) private parentComponent?: NodePermissionSubject) { @Inject(EXTENDIBLE_COMPONENT) private parentComponent?: NodePermissionSubject) {
} }
ngAfterViewInit() {
this.updateElement();
}
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
if (changes.nodes && !changes.nodes.firstChange) { if (changes.nodes && !changes.nodes.firstChange) {
this.updateElement(); this.updateElement();
@ -75,6 +72,7 @@ export class NodePermissionDirective implements OnChanges, AfterViewInit {
private enable(): void { private enable(): void {
if (this.parentComponent) { if (this.parentComponent) {
this.parentComponent.disabled = false; this.parentComponent.disabled = false;
this.changeDetector.detectChanges();
} else { } else {
this.enableElement(); this.enableElement();
} }
@ -83,6 +81,7 @@ export class NodePermissionDirective implements OnChanges, AfterViewInit {
private disable(): void { private disable(): void {
if (this.parentComponent) { if (this.parentComponent) {
this.parentComponent.disabled = true; this.parentComponent.disabled = true;
this.changeDetector.detectChanges();
} else { } else {
this.disableElement(); this.disableElement();
} }