Skip to content

Commit

Permalink
fix(directive): Update inputs changes when both comp and inputs are c…
Browse files Browse the repository at this point in the history
…hanged

So that OnChanges hook is called only once

closes #88
  • Loading branch information
gund committed Apr 19, 2018
1 parent 1579ba3 commit 7a05b6a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 17 deletions.
31 changes: 28 additions & 3 deletions src/dynamic/dynamic.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('Directive: Dynamic', () => {
});

it('should trigger initially `OnChanges` life-cycle hook', () => {
injectedComp.ngOnChanges.and.callFake((changes: SimpleChanges) => {
injectedComp.ngOnChanges.mockImplementation((changes: SimpleChanges) => {
expect(changes.prop1).toBeDefined();
expect(changes.prop1.currentValue).toBe('prop1');
expect(changes.prop1.isFirstChange()).toBeTruthy();
Expand All @@ -87,7 +87,7 @@ describe('Directive: Dynamic', () => {

expect(injectedComp.ngOnChanges).toHaveBeenCalledTimes(1);

injectedComp.ngOnChanges.and.callFake((changes: SimpleChanges) => {
injectedComp.ngOnChanges.mockImplementation((changes: SimpleChanges) => {
expect(changes.prop1).toBeDefined();
expect(changes.prop1.currentValue).toBe('123');
expect(changes.prop1.isFirstChange()).toBeFalsy();
Expand All @@ -103,7 +103,7 @@ describe('Directive: Dynamic', () => {
});

it('should trigger `OnChanges` life-cycle hook if component instance was updated', () => {
injectedComp.ngOnChanges.and.callFake((changes: SimpleChanges) => {
injectedComp.ngOnChanges.mockImplementation((changes: SimpleChanges) => {
expect(changes.prop1).toBeDefined();
expect(changes.prop1.currentValue).toBe('prop1');
expect(changes.prop1.isFirstChange()).toBeTruthy();
Expand Down Expand Up @@ -142,6 +142,31 @@ describe('Directive: Dynamic', () => {
fixture.componentInstance['inputs'] = { ...fixture.componentInstance['inputs'] };
expect(() => fixture.detectChanges()).not.toThrow();
});

it('should call `ngOnChanges` once when inputs and component updated', () => {
fixture.detectChanges();
injectorComp.component.ngOnChanges.mockReset();

const inputs = fixture.componentInstance['inputs'];
fixture.componentInstance['inputs'] = { ...inputs, prop: 'any' };
const newInjectedComp = injectorComp.component = { ...injectorComp.component };

newInjectedComp.ngOnChanges.mockImplementation((changes: SimpleChanges) => {
expect(changes.prop).toBeDefined();
expect(changes.prop.currentValue).toBe('any');
expect(changes.prop.previousValue).toBeUndefined();
expect(changes.prop.isFirstChange()).toBeTruthy();

expect(changes.prop1).toBeDefined();
expect(changes.prop1.currentValue).toBe('prop1');
expect(changes.prop1.previousValue).toBeUndefined();
expect(changes.prop1.isFirstChange()).toBeTruthy();
});

fixture.detectChanges();

expect(newInjectedComp.ngOnChanges).toHaveBeenCalledTimes(1);
});
});

describe('inputs with `NgComponentOutlet`', () => {
Expand Down
24 changes: 11 additions & 13 deletions src/dynamic/dynamic.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,20 @@ export class DynamicDirective implements OnChanges, DoCheck, OnDestroy {
) { }

ngOnChanges(changes: SimpleChanges) {
if (this._componentInstChanged) {
this.updateInputs(true);
this.bindOutputs();
} else {
if (this._inputsChanged(changes)) {
const inputsChanges = this._getInputsChanges(this._inputs);
const compChanged = this._componentInstChanged;

if (inputsChanges) {
this._updateInputChanges(inputsChanges);
this.updateInputs(!this._lastInputChanges);
}
}
if (compChanged || this._inputsChanged(changes)) {
const inputsChanges = this._getInputsChanges(this._inputs);

if (this._outputsChanged(changes)) {
this.bindOutputs();
if (inputsChanges) {
this._updateInputChanges(inputsChanges);
}

this.updateInputs(compChanged || !this._lastInputChanges);
}

if (compChanged || this._outputsChanged(changes)) {
this.bindOutputs();
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/component-injector.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ export class ComponentInjectorComponent implements ComponentInjector {
}

export class MockedInjectedComponent {
ngOnChanges = jasmine.createSpy('ngOnChanges');
ngOnChanges = jest.fn();
onEvent = new EventEmitter<any>();
}

0 comments on commit 7a05b6a

Please sign in to comment.