showcase: controller as, accessing to parent controller from child ones
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sat, 19 Sep 2015 15:14:53 +0000 (17:14 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sat, 19 Sep 2015 15:14:53 +0000 (17:14 +0200)
It requires changing the names of controllers in HTML from something common (vm) to
something particular.

angularjs/showcase/src/showcase/app/users/users-child.controller.js
angularjs/showcase/src/showcase/app/users/users-child.controller.spec.js
angularjs/showcase/src/showcase/app/users/users.controller.js
angularjs/showcase/src/showcase/app/users/users.html

index 10c3045..bb1836c 100644 (file)
@@ -24,6 +24,7 @@
   /* @ngInject */
   function UsersChildController($rootScope, $scope, USERS) {
     var vm = this;
+
     var emitFact = {
       title: 'Snake and Scarlett',
       fact: 'it is canon'
       city: 'UserChild'
     };
 
+    // This is the right way for accessing to a parent controller from a child one when using the "Controller as" way.
+    // Problem: we need to name our controllers with something different to the "vm standard", otherwise
+    // here we wouldn't be able to access to the parent controller because it would have the same name as our child
+    // controller (vm). So, we need different names for parent and child controllers.
+    vm.valueForChildControllers = $scope.usersController.toBeCalledFromChildControllers();
+
     vm.getEmit = function () {
       $scope.$emit(USERS.SCOPE.EMIT_FACT, emitFact);
     };
index d253c6b..2b5faeb 100644 (file)
@@ -1,6 +1,15 @@
 describe('app.users', function() {
   'use strict';
 
+  var valueForChildControllers = {
+    variable: 'This is a variable from UsersController',
+    value: 'Hello child controller'
+  };
+  var usersController = {
+    toBeCalledFromChildControllers: function() {
+      return valueForChildControllers;
+    }
+  };
   var $rootScope;
   var $scope;
   var USERS;
@@ -14,9 +23,12 @@ describe('app.users', function() {
       USERS = _USERS_;
       $scope = $rootScope.$new();
 
+      $scope.usersController = usersController;
       spyOn($scope, '$emit');
       spyOn($rootScope, '$broadcast');
       jasmine.createSpy($scope, '$scope.$broadcast');
+      spyOn($scope.usersController, 'toBeCalledFromChildControllers')
+        .and.callThrough();
       UsersChildController = $controller('UsersChildController', {
         $rootScope: $rootScope,
         $scope: $scope,
@@ -29,6 +41,9 @@ describe('app.users', function() {
 
     it('should be created successfully', function () {
       expect(UsersChildController).toBeDefined();
+
+      expect($scope.usersController.toBeCalledFromChildControllers).toHaveBeenCalled();
+      expect(UsersChildController.valueForChildControllers).toEqual(valueForChildControllers);
     });
 
     it('should be called $scope.$emit', function () {
index e6086ca..7a8723b 100644 (file)
       lastName: 'M. O\'Hara',
       city: 'Atlanta'
     };
+    var valueForChildControllers = {
+      variable: 'This is a variable from UsersController',
+      value: 'Hello child controller'
+    };
 
     vm.getRootScopeBroadcast = function () {
       $rootScope.$broadcast(USERS.ROOTSCOPE.BROADCAST, rootScopeBroadcastUser);
@@ -45,6 +49,9 @@
       vm.emitFact = emitFact;
       console.log('usersOnEmitFact, events.name: ' + events.name);
     };
+    vm.toBeCalledFromChildControllers = function () {
+      return valueForChildControllers;
+    };
 
     $scope.$on(USERS.SCOPE.EMIT_FACT, vm.usersOnEmitFact);
   }
index 4627e0c..fba9854 100644 (file)
@@ -1,42 +1,47 @@
 <!DOCTYPE html>
-<div class="container" ng-controller="UsersController as vm">
-  <div>title = {{vm.emitFact.title}}</div>
-  <div>fact = {{vm.emitFact.fact}}</div>
-  <button type="button" class="btn btn-primary" ng-click="vm.getRootScopeBroadcast()">
+<div class="container" ng-controller="UsersController as usersController">
+  <div>title = {{usersController.emitFact.title}}</div>
+  <div>fact = {{usersController.emitFact.fact}}</div>
+  <button type="button" class="btn btn-primary" ng-click="usersController.getRootScopeBroadcast()">
     $rootScope.$broadcast
   </button>
 
-  <button type="button" class="btn btn-primary" ng-click="vm.getScopeBroadcast()">
+  <button type="button" class="btn btn-primary" ng-click="usersController.getScopeBroadcast()">
     $scope.$broadcast
   </button>
 
-  <div class="container" ng-controller="UsersChildController as vm">
-    <div>name = {{vm.broadcastUser.name}}</div>
-    <div>lastname = {{vm.broadcastUser.lastName}}</div>
-    <div>city = {{vm.broadcastUser.city}}</div>
+  <div class="container" ng-controller="UsersChildController as usersChildController">
+    <div>name = {{usersChildController.broadcastUser.name}}</div>
+    <div>lastname = {{usersChildController.broadcastUser.lastName}}</div>
+    <div>city = {{usersChildController.broadcastUser.city}}</div>
 
-    <button type="button" class="btn btn-primary" ng-click="vm.getEmit()">
+    <button type="button" class="btn btn-primary" ng-click="usersChildController.getEmit()">
       $scope.$emit fact
     </button>
     <br>
-    <button type="button" class="btn btn-primary" ng-click="vm.broadcastToSencondChild()">
+    <button type="button" class="btn btn-primary" ng-click="usersChildController.broadcastToSencondChild()">
       $scope.$broadcast and $rootScope.$broadcast to second child
     </button>
+    <br><br>
+    <label>controller as, retrieving value from parent controller:</label>
+    <br>
+    <div>valueForChildControllers.variable = {{usersChildController.valueForChildControllers.variable}}</div>
+    <div>valueForChildControllers.value = {{usersChildController.valueForChildControllers.value}}</div>
   </div>
-  <div class="container" ng-controller="UsersSecondChildController as vm">
+  <div class="container" ng-controller="UsersSecondChildController as usersSecondChildController">
     <br>
     <label>secondchild $scope.$on listening for $rootScope.$broadcast from UsersChildController:</label>
     <br>
-    <div>name = {{vm.rootScopeBroadcastUser.name}}</div>
-    <div>lastname = {{vm.rootScopeBroadcastUser.lastName}}</div>
-    <div>city = {{vm.rootScopeBroadcastUser.city}}</div>
+    <div>name = {{usersSecondChildController.rootScopeBroadcastUser.name}}</div>
+    <div>lastname = {{usersSecondChildController.rootScopeBroadcastUser.lastName}}</div>
+    <div>city = {{usersSecondChildController.rootScopeBroadcastUser.city}}</div>
 
     <br>
     <label>secondchild $scope.$on listening for $scope.$broadcast from UsersChildController, same level never works:</label>
     <br>
-    <div>name = {{vm.scopeBroadcastUser.name}}</div>
-    <div>lastname = {{vm.scopeBroadcastUser.lastName}}</div>
-    <div>city = {{vm.scopeBroadcastUser.city}}</div>
+    <div>name = {{usersSecondChildController.scopeBroadcastUser.name}}</div>
+    <div>lastname = {{usersSecondChildController.scopeBroadcastUser.lastName}}</div>
+    <div>city = {{usersSecondChildController.scopeBroadcastUser.city}}</div>
 
   </div>