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 #7951
This commit is contained in:
		
							parent
							
								
									5e2bc5c593
								
							
						
					
					
						commit
						247964af62
					
				| @ -1,6 +1,7 @@ | ||||
| export interface IModule { | ||||
|   config(fn: any): IModule; | ||||
|   directive(selector: string, factory: any): IModule; | ||||
|   component(selector: string, component: IComponent): IModule; | ||||
|   controller(name: string, type: any): IModule; | ||||
|   factory(key: string, factoryFn: any): IModule; | ||||
|   value(key: string, value: any): IModule; | ||||
| @ -59,6 +60,15 @@ export interface IDirectiveLinkFn { | ||||
|   (scope: IScope, instanceElement: IAugmentedJQuery, instanceAttributes: IAttributes, | ||||
|    controller: any, transclude: ITranscludeFunction): void; | ||||
| } | ||||
| export interface IComponent { | ||||
|   bindings?: Object; | ||||
|   controller?: any; | ||||
|   controllerAs?: string; | ||||
|   require?: any; | ||||
|   template?: any; | ||||
|   templateUrl?: any; | ||||
|   transclude?: any; | ||||
| } | ||||
| export interface IAttributes { $observe(attr: string, fn: (v: string) => void): void; } | ||||
| export interface ITranscludeFunction { | ||||
|   // If the scope is provided, then the cloneAttachFn must be as well.
 | ||||
|  | ||||
| @ -53,6 +53,7 @@ export class UpgradeNg1ComponentAdapterBuilder { | ||||
|                       self.outputs, self.propertyOutputs, self.checkProperties, self.propertyMap); | ||||
|                 } | ||||
|               ], | ||||
|               ngOnInit: 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 */ } | ||||
|             }); | ||||
| @ -106,6 +107,8 @@ export class UpgradeNg1ComponentAdapterBuilder { | ||||
|               this.propertyMap[outputName] = localName; | ||||
|             // don't break; let it fall through to '@'
 | ||||
|             case '@': | ||||
|             // handle the '<' binding of angular 1.5 components
 | ||||
|             case '<': | ||||
|               this.inputs.push(inputName); | ||||
|               this.inputsRename.push(inputNameRename); | ||||
|               this.propertyMap[inputName] = localName; | ||||
| @ -231,6 +234,13 @@ class UpgradeNg1ComponentAdapter implements OnChanges, DoCheck { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   ngOnInit() { | ||||
|     if (this.destinationObj.$onInit) { | ||||
|       this.destinationObj.$onInit(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   ngOnChanges(changes: {[name: string]: SimpleChange}) { | ||||
|     for (var name in changes) { | ||||
|       if ((<Object>changes).hasOwnProperty(name)) { | ||||
|  | ||||
| @ -561,6 +561,65 @@ export function main() { | ||||
|                }); | ||||
|          })); | ||||
| 
 | ||||
|       it('should call $onInit of components', inject([AsyncTestCompleter], (async) => { | ||||
|            var adapter = new UpgradeAdapter(); | ||||
|            var ng1Module = angular.module('ng1', []); | ||||
|            var valueToFind = '$onInit'; | ||||
| 
 | ||||
|            var ng1 = { | ||||
|              bindings: {}, | ||||
|              template: '{{$ctrl.value}}', | ||||
|              controller: Class( | ||||
|                  {constructor: function() {}, $onInit: function() { this.value = valueToFind; }}) | ||||
|            }; | ||||
|            ng1Module.component('ng1', ng1); | ||||
| 
 | ||||
|            var Ng2 = Component({ | ||||
|                        selector: 'ng2', | ||||
|                        template: '<ng1></ng1>', | ||||
|                        directives: [adapter.upgradeNg1Component('ng1')] | ||||
|                      }).Class({constructor: function() {}}); | ||||
|            ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); | ||||
| 
 | ||||
|            var element = html(`<div><ng2></ng2></div>`); | ||||
|            adapter.bootstrap(element, ['ng1']) | ||||
|                .ready((ref) => { | ||||
|                  expect(multiTrim(document.body.textContent)).toEqual(valueToFind); | ||||
|                  ref.dispose(); | ||||
|                  async.done(); | ||||
|                }); | ||||
|          })); | ||||
| 
 | ||||
|       it('should bind input properties (<) of components', inject([AsyncTestCompleter], (async) => { | ||||
|            var adapter = new UpgradeAdapter(); | ||||
|            var ng1Module = angular.module('ng1', []); | ||||
| 
 | ||||
|            var ng1 = { | ||||
|              bindings: {personProfile: '<'}, | ||||
|              template: 'Hello {{$ctrl.personProfile.firstName}} {{$ctrl.personProfile.lastName}}', | ||||
|              controller: Class({constructor: function() {}}) | ||||
|            }; | ||||
|            ng1Module.component('ng1', ng1); | ||||
| 
 | ||||
|            var Ng2 = | ||||
|                Component({ | ||||
|                  selector: 'ng2', | ||||
|                  template: '<ng1 [personProfile]="goku"></ng1>', | ||||
|                  directives: [adapter.upgradeNg1Component('ng1')] | ||||
|                }) | ||||
|                    .Class({ | ||||
|                      constructor: function() { this.goku = {firstName: 'GOKU', lastName: 'SAN'}; } | ||||
|                    }); | ||||
|            ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); | ||||
| 
 | ||||
|            var element = html(`<div><ng2></ng2></div>`); | ||||
|            adapter.bootstrap(element, ['ng1']) | ||||
|                .ready((ref) => { | ||||
|                  expect(multiTrim(document.body.textContent)).toEqual(`Hello GOKU SAN`); | ||||
|                  ref.dispose(); | ||||
|                  async.done(); | ||||
|                }); | ||||
|          })); | ||||
|     }); | ||||
| 
 | ||||
|     describe('injection', () => { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user