fix(upgrade): call ng1 lifecycle hooks (#12875)
This commit is contained in:
parent
07a986d330
commit
1ef4696cb7
|
@ -49,7 +49,8 @@ export class UpgradeNg1ComponentAdapterBuilder {
|
||||||
],
|
],
|
||||||
ngOnInit: function() { /* needs to be here for ng2 to properly detect it */ },
|
ngOnInit: function() { /* needs to be here for ng2 to properly detect it */ },
|
||||||
ngOnChanges: function() { /* needs to be here for ng2 to properly detect it */ },
|
ngOnChanges: function() { /* needs to be here for ng2 to properly detect it */ },
|
||||||
ngDoCheck: function() { /* needs to be here for ng2 to properly detect it */ }
|
ngDoCheck: function() { /* needs to be here for ng2 to properly detect it */ },
|
||||||
|
ngOnDestroy: function() { /* needs to be here for ng2 to properly detect it */ },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,16 +263,18 @@ class UpgradeNg1ComponentAdapter implements OnInit, OnChanges, DoCheck {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
for (const name in changes) {
|
const ng1Changes: any = {};
|
||||||
if ((<Object>changes).hasOwnProperty(name)) {
|
Object.keys(changes).forEach(name => {
|
||||||
const change: SimpleChange = changes[name];
|
const change: SimpleChange = changes[name];
|
||||||
this.setComponentProperty(name, change.currentValue);
|
this.setComponentProperty(name, change.currentValue);
|
||||||
}
|
ng1Changes[this.propertyMap[name]] = change;
|
||||||
|
});
|
||||||
|
if (this.destinationObj.$onChanges) {
|
||||||
|
this.destinationObj.$onChanges(ng1Changes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngDoCheck(): number {
|
ngDoCheck() {
|
||||||
const count = 0;
|
|
||||||
const destinationObj = this.destinationObj;
|
const destinationObj = this.destinationObj;
|
||||||
const lastValues = this.checkLastValues;
|
const lastValues = this.checkLastValues;
|
||||||
const checkProperties = this.checkProperties;
|
const checkProperties = this.checkProperties;
|
||||||
|
@ -287,7 +290,15 @@ class UpgradeNg1ComponentAdapter implements OnInit, OnChanges, DoCheck {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
if (this.destinationObj.$doCheck && this.directive.controller) {
|
||||||
|
this.destinationObj.$doCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
if (this.destinationObj.$onDestroy && this.directive.controller) {
|
||||||
|
this.destinationObj.$onDestroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setComponentProperty(name: string, value: any) {
|
setComponentProperty(name: string, value: any) {
|
||||||
|
|
|
@ -922,6 +922,127 @@ export function main() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should call $doCheck of components', async(() => {
|
||||||
|
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
||||||
|
const ng1Module = angular.module('ng1', []);
|
||||||
|
const valueToFind = '$doCheck';
|
||||||
|
|
||||||
|
let spy = jasmine.createSpy('doCheck');
|
||||||
|
|
||||||
|
const ng1 = {
|
||||||
|
bindings: {},
|
||||||
|
template: '{{$ctrl.value}}',
|
||||||
|
controller: Class({
|
||||||
|
constructor: function() {},
|
||||||
|
$doCheck: function() {
|
||||||
|
this.value = valueToFind;
|
||||||
|
spy();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
ng1Module.component('ng1', ng1);
|
||||||
|
|
||||||
|
const Ng2 = Component({selector: 'ng2', template: '<ng1></ng1>'}).Class({
|
||||||
|
constructor: function() {}
|
||||||
|
});
|
||||||
|
|
||||||
|
const Ng2Module = NgModule({
|
||||||
|
declarations: [adapter.upgradeNg1Component('ng1'), Ng2],
|
||||||
|
imports: [BrowserModule],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
|
}).Class({constructor: function() {}});
|
||||||
|
|
||||||
|
ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2));
|
||||||
|
|
||||||
|
const element = html(`<div><ng2></ng2></div>`);
|
||||||
|
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
||||||
|
expect(multiTrim(document.body.textContent)).toEqual(valueToFind);
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
|
let count = spy.calls.count();
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(spy.calls.count()).toBeGreaterThan(count);
|
||||||
|
ref.dispose();
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should call $onChanges of components', async(() => {
|
||||||
|
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
||||||
|
const ng1Module = angular.module('ng1', []);
|
||||||
|
const valueToFind = '$onChanges init';
|
||||||
|
const valueToChange = '$onChanges changed';
|
||||||
|
|
||||||
|
const ng1 = {
|
||||||
|
bindings: {val: '<'},
|
||||||
|
template: '{{$ctrl.value}}',
|
||||||
|
controller: Class({
|
||||||
|
constructor: function() {},
|
||||||
|
$onChanges: function(changes: any) { this.value = changes.val.currentValue; }
|
||||||
|
})
|
||||||
|
};
|
||||||
|
ng1Module.component('ng1', ng1);
|
||||||
|
|
||||||
|
const Ng2 = Component({selector: 'ng2', template: '<ng1 [val]="val"></ng1>'}).Class({
|
||||||
|
constructor: function() { this.val = valueToFind; },
|
||||||
|
ngOnInit: function() { setTimeout(() => { this.val = valueToChange; }, 100); }
|
||||||
|
});
|
||||||
|
|
||||||
|
const Ng2Module = NgModule({
|
||||||
|
declarations: [adapter.upgradeNg1Component('ng1'), Ng2],
|
||||||
|
imports: [BrowserModule],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
|
}).Class({constructor: function() {}});
|
||||||
|
|
||||||
|
ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2));
|
||||||
|
|
||||||
|
const element = html(`<div><ng2></ng2></div>`);
|
||||||
|
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
||||||
|
expect(multiTrim(document.body.textContent)).toEqual(valueToFind);
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(multiTrim(document.body.textContent)).toEqual(valueToChange);
|
||||||
|
ref.dispose();
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should call $onDestroy of components', async(() => {
|
||||||
|
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
||||||
|
const ng1Module = angular.module('ng1', []);
|
||||||
|
|
||||||
|
let spy = jasmine.createSpy('$onDestroy');
|
||||||
|
|
||||||
|
const ng1 = {
|
||||||
|
bindings: {},
|
||||||
|
template: '<div>ng1</div>',
|
||||||
|
controller: function($rootScope: any) { this.$onDestroy = function() { spy(); }; }
|
||||||
|
};
|
||||||
|
ng1Module.component('ng1', ng1);
|
||||||
|
|
||||||
|
const Ng2 = Component({selector: 'ng2', template: '<ng1></ng1>'}).Class({
|
||||||
|
constructor: function() {}
|
||||||
|
});
|
||||||
|
|
||||||
|
const Ng2Module = NgModule({
|
||||||
|
declarations: [adapter.upgradeNg1Component('ng1'), Ng2],
|
||||||
|
imports: [BrowserModule],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
|
}).Class({constructor: function() {}});
|
||||||
|
|
||||||
|
ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2));
|
||||||
|
|
||||||
|
const element = html(`<div ng-if="!destroy"><ng2></ng2></div>`);
|
||||||
|
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
||||||
|
(<any>ref.ng1RootScope).destroy = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
(<any>ref.ng1RootScope).destroy = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
|
ref.dispose();
|
||||||
|
}, 100);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should bind input properties (<) of components', async(() => {
|
it('should bind input properties (<) of components', async(() => {
|
||||||
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
||||||
const ng1Module = angular.module('ng1', []);
|
const ng1Module = angular.module('ng1', []);
|
||||||
|
|
Loading…
Reference in New Issue