23

Is there a way of inheriting the parent scope while extending it with passed attributes?

I want to pass parameters to a reusable directive directly from the template without having to alter the DOM in the linking function.

For example:

<form-input icon="icon-email" label="email" ng-model="data.input"></form-input>

For a directive like this:

    <div class="form-group">
      <label>{{label}}</label>
      <div class="input-group">
        <div class="{{icon}}">@</div>
        <input class="form-control" placeholder="Email" ng-model="mail.email">
      </div>
    </div>

ng-model is in the parent scope, controlling an entire form in this case, but I don't think it's necessary to store styling attributes in the controller.

Is there a way of passing parameters directly in the template without creating an isolate scope?

2 Answers 2

29

You would not be able to 'extend' the parent scope as such. However your objective can be accomplished by utilizing the directive tag attributes that are injected in the link function of your directive.

So eg. for attaching your label variable, your directive's link function would look like below:

 link: function ($scope, $element, $attributes) {
         $scope.label = $scope.$eval($attributes.label);
        }


You can check out the below plunker for a live demo.
http://plnkr.co/edit/2qMgJSSlDyU6VwdUoYB7?p=preview

Sign up to request clarification or add additional context in comments.

3 Comments

I guess there's no way around the link then. Your plunk is just what I needed.
I removed the "$scope.$eval" part, and used the value directly supplied in "$attributes", since I'm expecting string, and don't want the users of the directive to have to wrap everything with quotes. Is that a bad practice? Thanks for the solution by the way !
@eitanfar To pass in a literal, you're right - you don't need to call `$scope.$eval', since there's nothing to interpolate. stackoverflow.com/a/15671573/3123195 has a good high-level explanation as well as links to the docs.
8

The answer from Angad will work for static linking, but if the value of the attribute can change after linking, this will not be updated. If you need this, the sollution would be to pass the value as string instead of reference:

<form-input icon="icon-email" label="{{email}}" ng-model="data.input"></form-input>

In the directive, add an $observe on the attribute to update the scope variable:

$attributes.$observe('label', function(newValue){$scope.label=newValue});

Now the scope variable will dynamically change if the attribute value change.

1 Comment

can you do a two way data binding this way? without isolated scope?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.