diff --git a/modules/@angular/upgrade/src/upgrade_ng1_adapter.ts b/modules/@angular/upgrade/src/upgrade_ng1_adapter.ts index ffbee23654..a45768fe7e 100644 --- a/modules/@angular/upgrade/src/upgrade_ng1_adapter.ts +++ b/modules/@angular/upgrade/src/upgrade_ng1_adapter.ts @@ -186,33 +186,22 @@ class UpgradeNg1ComponentAdapter implements OnInit, OnChanges, DoCheck { checkLastValues: any[] = []; componentScope: angular.IScope; element: Element; + $element: any = null; constructor(private linkFn: angular.ILinkFn, scope: angular.IScope, private directive: angular.IDirective, elementRef: ElementRef, - $controller: angular.IControllerService, private inputs: string[], + private $controller: angular.IControllerService, private inputs: string[], private outputs: string[], private propOuts: string[], private checkProperties: string[], private propertyMap: {[key: string]: string}) { this.element = elementRef.nativeElement; this.componentScope = scope.$new(!!directive.scope); - var $element = angular.element(this.element); + this.$element = angular.element(this.element); var controllerType = directive.controller; - var controller: any = null; - if (controllerType) { - var locals = {$scope: this.componentScope, $element: $element}; - controller = $controller(controllerType, locals, null, directive.controllerAs); - $element.data(controllerKey(directive.name), controller); + if (directive.bindToController && controllerType) { + this.destinationObj = this.buildController(controllerType); + } else { + this.destinationObj = this.componentScope; } - var link = directive.link; - if (typeof link == 'object') link = (link).pre; - if (link) { - var attrs: angular.IAttributes = NOT_SUPPORTED; - var transcludeFn: angular.ITranscludeFunction = NOT_SUPPORTED; - var linkController = this.resolveRequired($element, directive.require); - (directive.link)(this.componentScope, $element, attrs, - linkController, transcludeFn); - } - this.destinationObj = - directive.bindToController && controller ? controller : this.componentScope; for (var i = 0; i < inputs.length; i++) { this[inputs[i]] = null; @@ -225,9 +214,24 @@ class UpgradeNg1ComponentAdapter implements OnInit, OnChanges, DoCheck { this[propOuts[k]] = new EventEmitter(); this.checkLastValues.push(INITIAL_VALUE); } + } ngOnInit() { + + if (!this.directive.bindToController && this.directive.controller) { + this.buildController(this.directive.controller) + } + var link = this.directive.link; + if (typeof link == 'object') link = (link).pre; + if (link) { + var attrs: angular.IAttributes = NOT_SUPPORTED; + var transcludeFn: angular.ITranscludeFunction = NOT_SUPPORTED; + var linkController = this.resolveRequired(this.$element, this.directive.require); + (this.directive.link)(this.componentScope, this.$element, attrs, + linkController, transcludeFn); + } + var childNodes: Node[] = []; var childNode; while (childNode = this.element.firstChild) { @@ -277,6 +281,13 @@ class UpgradeNg1ComponentAdapter implements OnInit, OnChanges, DoCheck { this.destinationObj[this.propertyMap[name]] = value; } + private buildController(controllerType) { + var locals = { $scope: this.componentScope, $element: this.$element }; + var controller:any = this.$controller(controllerType, locals, null, this.directive.controllerAs); + this.$element.data(controllerKey(this.directive.name), controller); + return controller; + } + private resolveRequired($element: angular.IAugmentedJQuery, require: string | string[]): any { if (!require) { return undefined; diff --git a/modules/@angular/upgrade/test/upgrade_spec.ts b/modules/@angular/upgrade/test/upgrade_spec.ts index da961434ae..47ae40089b 100644 --- a/modules/@angular/upgrade/test/upgrade_spec.ts +++ b/modules/@angular/upgrade/test/upgrade_spec.ts @@ -314,6 +314,94 @@ export function main() { }); })); + it('should bind properties, events in controller when bindToController is not used', inject([AsyncTestCompleter], (async) => { + var adapter = new UpgradeAdapter(); + var ng1Module = angular.module('ng1', []); + + var ng1 = function() { + return { + restrict: 'E', + template: '{{someText}} - Length: {{data.length}}', + scope: { data: "="}, + controller: function($scope) { + $scope.someText = "ng1 - Data: " + $scope.data; + } + }; + }; + + ng1Module.directive('ng1', ng1); + var Ng2 = Component({ + selector: 'ng2', + template: '{{someText}} - Length: {{dataList.length}} | ', + directives: [adapter.upgradeNg1Component('ng1')], + }) + .Class({ + + constructor: function() { + this.dataList = [1, 2, 3]; + this.someText = "ng2" + } + }); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + var element = html(`
`); + adapter.bootstrap(element, ['ng1']) + .ready((ref) => { + // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule + // events, and so without this we would not see the events processed. + setTimeout(() => { + expect(multiTrim(document.body.textContent)) + .toEqual( + "ng2 - Length: 3 | ng1 - Data: 1,2,3 - Length: 3"); + ref.dispose(); + async.done(); + }, 0); + }); + })); + + it('should bind properties, events in link function', inject([AsyncTestCompleter], (async) => { + var adapter = new UpgradeAdapter(); + var ng1Module = angular.module('ng1', []); + + var ng1 = function() { + return { + restrict: 'E', + template: '{{someText}} - Length: {{data.length}}', + scope: { data: "=" }, + link: function($scope) { + $scope.someText = "ng1 - Data: " + $scope.data; + } + }; + }; + + ng1Module.directive('ng1', ng1); + var Ng2 = Component({ + selector: 'ng2', + template: '{{someText}} - Length: {{dataList.length}} | ', + directives: [adapter.upgradeNg1Component('ng1')], + }) + .Class({ + + constructor: function() { + this.dataList = [1, 2, 3]; + this.someText = "ng2" + } + }); + ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2)); + var element = html(`
`); + adapter.bootstrap(element, ['ng1']) + .ready((ref) => { + // we need to do setTimeout, because the EventEmitter uses setTimeout to schedule + // events, and so without this we would not see the events processed. + setTimeout(() => { + expect(multiTrim(document.body.textContent)) + .toEqual( + "ng2 - Length: 3 | ng1 - Data: 1,2,3 - Length: 3"); + ref.dispose(); + async.done(); + }, 0); + }); + })); + it('should support templateUrl fetched from $httpBackend', inject([AsyncTestCompleter], (async) => { var adapter = new UpgradeAdapter();