X Tutup
Skip to content

Commit 247964a

Browse files
kevinmerckxalxhub
authored andcommitted
fix(upgrade): make upgradeAdapter upgrade angular 1 components correctly
With this fix, the $onInit function of an upgraded angular 1 component is called and input bindings (<) are created. Closes angular#7951
1 parent 5e2bc5c commit 247964a

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

modules/angular2/src/upgrade/angular_js.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export interface IModule {
22
config(fn: any): IModule;
33
directive(selector: string, factory: any): IModule;
4+
component(selector: string, component: IComponent): IModule;
45
controller(name: string, type: any): IModule;
56
factory(key: string, factoryFn: any): IModule;
67
value(key: string, value: any): IModule;
@@ -59,6 +60,15 @@ export interface IDirectiveLinkFn {
5960
(scope: IScope, instanceElement: IAugmentedJQuery, instanceAttributes: IAttributes,
6061
controller: any, transclude: ITranscludeFunction): void;
6162
}
63+
export interface IComponent {
64+
bindings?: Object;
65+
controller?: any;
66+
controllerAs?: string;
67+
require?: any;
68+
template?: any;
69+
templateUrl?: any;
70+
transclude?: any;
71+
}
6272
export interface IAttributes { $observe(attr: string, fn: (v: string) => void): void; }
6373
export interface ITranscludeFunction {
6474
// If the scope is provided, then the cloneAttachFn must be as well.

modules/angular2/src/upgrade/upgrade_ng1_adapter.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export class UpgradeNg1ComponentAdapterBuilder {
5353
self.outputs, self.propertyOutputs, self.checkProperties, self.propertyMap);
5454
}
5555
],
56+
ngOnInit: function() { /* needs to be here for ng2 to properly detect it */ },
5657
ngOnChanges: function() { /* needs to be here for ng2 to properly detect it */ },
5758
ngDoCheck: function() { /* needs to be here for ng2 to properly detect it */ }
5859
});
@@ -106,6 +107,8 @@ export class UpgradeNg1ComponentAdapterBuilder {
106107
this.propertyMap[outputName] = localName;
107108
// don't break; let it fall through to '@'
108109
case '@':
110+
// handle the '<' binding of angular 1.5 components
111+
case '<':
109112
this.inputs.push(inputName);
110113
this.inputsRename.push(inputNameRename);
111114
this.propertyMap[inputName] = localName;
@@ -231,6 +234,13 @@ class UpgradeNg1ComponentAdapter implements OnChanges, DoCheck {
231234
}
232235
}
233236

237+
238+
ngOnInit() {
239+
if (this.destinationObj.$onInit) {
240+
this.destinationObj.$onInit();
241+
}
242+
}
243+
234244
ngOnChanges(changes: {[name: string]: SimpleChange}) {
235245
for (var name in changes) {
236246
if ((<Object>changes).hasOwnProperty(name)) {

modules/angular2/test/upgrade/upgrade_spec.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,65 @@ export function main() {
561561
});
562562
}));
563563

564+
it('should call $onInit of components', inject([AsyncTestCompleter], (async) => {
565+
var adapter = new UpgradeAdapter();
566+
var ng1Module = angular.module('ng1', []);
567+
var valueToFind = '$onInit';
568+
569+
var ng1 = {
570+
bindings: {},
571+
template: '{{$ctrl.value}}',
572+
controller: Class(
573+
{constructor: function() {}, $onInit: function() { this.value = valueToFind; }})
574+
};
575+
ng1Module.component('ng1', ng1);
576+
577+
var Ng2 = Component({
578+
selector: 'ng2',
579+
template: '<ng1></ng1>',
580+
directives: [adapter.upgradeNg1Component('ng1')]
581+
}).Class({constructor: function() {}});
582+
ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2));
583+
584+
var element = html(`<div><ng2></ng2></div>`);
585+
adapter.bootstrap(element, ['ng1'])
586+
.ready((ref) => {
587+
expect(multiTrim(document.body.textContent)).toEqual(valueToFind);
588+
ref.dispose();
589+
async.done();
590+
});
591+
}));
592+
593+
it('should bind input properties (<) of components', inject([AsyncTestCompleter], (async) => {
594+
var adapter = new UpgradeAdapter();
595+
var ng1Module = angular.module('ng1', []);
596+
597+
var ng1 = {
598+
bindings: {personProfile: '<'},
599+
template: 'Hello {{$ctrl.personProfile.firstName}} {{$ctrl.personProfile.lastName}}',
600+
controller: Class({constructor: function() {}})
601+
};
602+
ng1Module.component('ng1', ng1);
603+
604+
var Ng2 =
605+
Component({
606+
selector: 'ng2',
607+
template: '<ng1 [personProfile]="goku"></ng1>',
608+
directives: [adapter.upgradeNg1Component('ng1')]
609+
})
610+
.Class({
611+
constructor: function() { this.goku = {firstName: 'GOKU', lastName: 'SAN'}; }
612+
});
613+
ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2));
614+
615+
var element = html(`<div><ng2></ng2></div>`);
616+
adapter.bootstrap(element, ['ng1'])
617+
.ready((ref) => {
618+
expect(multiTrim(document.body.textContent)).toEqual(`Hello GOKU SAN`);
619+
ref.dispose();
620+
async.done();
621+
});
622+
}));
564623
});
565624

566625
describe('injection', () => {

0 commit comments

Comments
 (0)
X Tutup