Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

new scope that inherits from parent within angular directives

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?

like image 917
pillarOfLight Avatar asked Apr 06 '13 21:04

pillarOfLight


People also ask

How do I get parent scope in directive?

You can still access the parent scope using $parent , but this is not normally recommended. Instead, you should specify which parent scope properties (and/or function) the directive needs via additional attributes on the same element where the directive is used, using the = , @ , and & notation.

What is scope parent?

Angular scopes include a variable called $parent (i.e. $scope. $parent ) that refer to the parent scope of a controller. If a controller is at the root of the application, the parent would be the root scope ( $rootScope ). Child controllers can therefore modify the parent scope since they access to it.

What is the best scope to be used for reusable directives in AngularJS?

Isolate Scope: If the need is to reuse the component (directive) throughout your app, consider creating isolate scopes using scope option. The concept of isolate scope is used to separate the scope inside a directive from the scope outside.

What is the default scope in an angular directive?

By default, directives do not create their own scope; instead they use the scope of their parent, generally a controller (within the scope of which the directive is defined). We can change the default scope of the directive using the scope field of the DDO (Data Definition Object).


1 Answers

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();
     });
    }
like image 189
Mark Rajcok Avatar answered Oct 12 '22 13:10

Mark Rajcok