How to avoid using `$parent.$parent.$parent` in ne

2019-09-01 03:39发布

问题:

How can I know the Parent controller name in controller chain of Angular?

I'm new to Angular so I have one basic question.

Suppose, In Angular, I have a controller's chain like below.

<div ng-controller="parentController">
  ... something in the parent element
  <div ng-controller="childController">
     ... something in the child element
  </div>
</div>

Is there any way to write the code in the child element so that I can know the parent controller name in the output (In this case output should be 'parentController')?

I need this because I have a too big project and want to know the parent of each controller because someone has wrote the code like

googleOAuth= $scope.$parent.$parent.$parent.$parent.status.googleOAuth

and I'm not able to understand so want to know the parent of each $scope.

回答1:

On approach is to use "controller as" syntax:

<div ng-controller="parentController as top">
     <!-- ... something in the parent element -->
  <div ng-controller="childController">
     <!-- ... something in the child element -->
     {{top.status.googleOAuth}}
  </div>
</div>

This requires the controller be written using the this context instead of $scope.


Another approach is to use a property of an object in the parent scope:

app.controller("parentController", function($scope) {
    $scope.top = {status: {} };
    $scope.top.status.googleOAuth = value;
});
<div ng-controller="parentController">
     <!-- ... something in the parent element -->
  <div ng-controller="childController">
     <!-- ... something in the child element -->
     {{top.status.googleOAuth}}
  </div>
</div>

Because scopes use prototypical inheritance, the top property is available to child scopes.

See AngularJS Developer Guide - Scope Hierarchies.



回答2:

As georgeawg said, using $parent is not optimal because it relies on a constant number of scopes.

Instead, you could write a service to deal with your googleOAuth. The service can then be injected in each controller and will function as a single source of truth because services are singletons in AngularJS.

e.g. something like this

angular.module('appModule', [])
    .factory('googleOAuthService', [function() {
        var googleOAuth = {
            // your googleOAuth stuff here
        };

        return {
            get: get,
            set: set,
            stuff: stuff
        }

        function get () {
            return googleOAuth;
        }

        function set (newGoogleOAuth) {
            googleOAuth = newGoogleOAuth;
        }

        function stuff () {
            // Do stuff to googleOAuth
        }
    }])
    .controller('parentController', ['googleOAuthService', function(googleOAuthService) {
        googleOAuthService.stuff();
    }])
    .controller('childController', ['googleOAuthService', function(googleOAuthService) {
        googleOAuthService.stuff();
    }]);

For more info, see https://docs.angularjs.org/guide/services