简体   繁体   中英

Is it a good practice to use $parent in angular?

I'm a newbie in the world of Angular and I would like to know if it's a good practice to use the $parent global variable to access a parent scope. For instance, a data-ng-if creates an isolated scope which causes sometimes some problems for accessing the parent scope, so the only way to do that is $parent.myVariable .

Any example, any advice to make sure that my code is clean and follows the good practices would be appreciable.

It's not a good practice, it will cause you troubles. Let's say you have a <div> binded to a controller and a <div ng-if> , you decide to use inside your dive {{ $parent.myVariable }} . What happend if you need to nest inside another ng-if ? or to remove the only ng-if ?

I suggest you to save variables inside an object stored in controller $scope variable.
So you should have something like this in your controller.

$scope.MyValues = {};
$scope.MyValues.myVariable = 5;

Now you can avoid using $parent inside your <div> and look safely for {{ MyValues.myVariable }} and angular will fall back through $parent until it found the MyValues object, so you can (almost) forget ng-if scope problems. The same apply to nested controllers.

Here a fast reference to these kind of best practice: learn-how-to-use-scopes-properly-in-angularjs

The ng-if directive should see the parent scope regardless, see demo .

In the case of isolate scopes on directives, it's better the pass the $scope objects down through an interface, rather than count on the existence of the property on the $parent :

app.controller("myCtrl", function($scope){
    $scope.foo = "bar";
});

app.directive("myDirective", function(){
    return {
        scope: {
            // expect foo to be passed to the directive
            // = means conserve bi directional binding
            foo: "=" 
        },
        link: function(scope) {
            ... // scope.foo is defined
        }
    }
});

In the view

<div ng-controller="myCtrl">
    <my-directive foo="foo"></my-directive>
</div>

The best practice is to make your directives decoupled , it should be self contained and if directives need external aspects, you can inject them or bind them. not good to rely on something to be used in a specific context.

One example is :

<div ng-controller="Parent as parent">

  <div ng-if="parent.showMessage">
    Some simple message.
  </div>

  <div child-one parent="parent"></div>

</div>

Controller

app.controller('Parent', function () {
    var self = this;
    self.showMessage = true;
});

app.directive('childOne', function() {
    return {
        controllerAs: 'childOne',
        controller: function($scope, $attrs) {
            var parent = $scope.$eval($attrs.parent);

            var self = this;
            self.foo = 'bar';
            // Some simple logic.
            if (self.foo === 'bar') {
                parent.showMessage = false;
            }
        }
    };
});

It seems perfectly okay to do so.

<div ng-app ng-controller="NameCtrl">
    <div ng-controller="ChildCtrl as vm">
       {{$parent.names}}
    </div>
</div>

function NameCtrl($scope) {
    $scope.names = ["Tom", "Dick", "Harry"];
}

function ChildCtrl($scope) {
    $scope.parentnames = $scope.$parent.names;
}

See: http://jsfiddle.net/8bojdnpt/

From a good practice point of view, this method is also good because you can also destroy unneeded scopes so they don't remain in buffer.

However, John Papa advises against the use of $parent : https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#controllers . Instead, he would prefer you use the controller as syntax.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM