new scope that inherits from parent within angular directives

13,042

how can I make the scope of this directive inherit a variable from the parent scope and yet still have it to be an 'isolate' scope

Using the word "inherit" here is a bit confusing. An isolate scope does not (prototypically) inherit from its parent scope. Angular does put a $parent property on the isolate scope, so you could access parent scope properties that way, but best practice is to not use $parent. If you want an isolate scope, the only way to pass parent scope property values into that isolate scope is to use =, @, or &. All three will actually work (even '&' could be used to pass property values via an expression – for the curious).

On your isolate scope (or if you use scope: true), you can create new properties. These new properties will not propagate back to the parent. So, if you want to alter a property value that you passed into the directive, you can simply copy it to some new property on the directive's scope.

Here's an example using @, the "one-way string" syntax. To get the (interpolated) value of your parent scope property (as a string), use {{}}s in the HTML:

<div class="dostuff" some-var="{{interpolateThisParentScopePropertyPlease}}">

sAngular.app.directive('dostuff', ['$compile', function($compile){
  return   {
    restrict : 'C',
    scope: { someVar : '@' },
    link : function(scope, element, attrs){  
      element.click(function(){
        scope.myLocalDirectiveProperty = scope.someVar;
        scope.someOtherDirectiveProperty = 'somethingelse';
        var dropdownOutput = template();
        var compiledOutput = $compile(dropdownOutput)(scope);
        scope.$apply();
     });
    }

If you want to pass an object to the directive, use the '=' syntax, and then use angular.copy() to make a copy of the object inside the directive.


As per the comment request:

<div class="dostuff" some-obj="parentScopeObj">

sAngular.app.directive('dostuff', ['$compile', function($compile){
  return   {
    restrict : 'C',
    scope: { someObj : '=' },
    link : function(scope, element, attrs){  
      element.click(function(){
        scope.myLocalDirectiveObjProperty = angular.copy(scope.someObj);
        ...
        scope.$apply();
     });
    }
Share:
13,042
pillarOfLight
Author by

pillarOfLight

Updated on June 07, 2022

Comments

  • pillarOfLight
    pillarOfLight about 2 years

    suppose I do this:

    sAngular.app.directive('dostuff', ['$compile', function($compile){
      return   {
        restrict : 'C',
        scope: {
          someVar : '='
        },
        link : function(scope, element, attrs){  
          element.click(function(){
               //do stuff
            scope.someVar = 'somethingelse';
            var dropdownOutput = template();
            var compiledOutput = $compile(dropdownOutput)(scope);
            scope.$apply();
         });
        }    
      }
    }]);
    

    how can I make the scope of this directive inherit a variable from the parent scope and yet still have it to be an 'isolate' scope

    for instance from angular docs:

    = or =attr - set up bi-directional binding between a local scope property and the parent scope property of name defined via the value of the attr attribute. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localModel:'=myAttr' }, then widget scope property localModel will reflect the value of parentModel on the parent scope. Any changes to parentModel will be reflected in localModel and any changes in localModel will reflect in parentModel.

    however in that case since "any changes in localModel will reflect in parentModel" if I modify a variable in the scope in that directive and then do scope.apply() in that case, it will reflect in the parent scope accordingly and the parent template will be updated with the changes

    I also tried doing "scope : true" as a parameter but changes to the scope there followed by the scope.$apply(); will also propagate to the original scope...

    Is there a way to make it so that I can copy a scope from the parent scope and still have changes in the variables in that scope not propagate to the parent scope?