0

I want to pass a product's id to a directive like so:

<widget product-id="product.id"></widget>

I prefer not to use curly braces:

<widget product-id="{{product.id}}"></widget>

because it's more verbose, and I want to match the style of ng-model usage.

I want to use isolate scope so that I can't accidentally modify product.id inside the widget.

If I use:

scope {
  productId: '@'
}

Then in my directive template: {{productId}} gives me the string "product.id"

If I use:

scope {
  productId: '&'
}

I see no output in my directive template {{productId}}, and as I understand it & is for binding functions not properties.

If I use:

scope {
  productId: '='
}

I get the exact value that I want (a number), but isn't this two-way binding and vulnerable to changing the product.id in the widget?

3
  • What are you doing with the ID? You should pass in the whole model if you need it... You shouldn't need to pass in a ID somewhere. Commented Jan 11, 2014 at 1:38
  • If you are afraid to change it, then just remove it from the scope after you've used it or stored in a variable. Commented Jan 11, 2014 at 17:26
  • I'm grabbing images for the product. I don't think I require the whole model. Commented Jan 12, 2014 at 2:10

2 Answers 2

0

If you want to avoid the double curlys you can use $parse to process the Angular expression yourself:

Expressions are JavaScript-like code snippets that are usually placed in bindings such as {{ expression }}. Expressions are processed by the $parse service.

To use $parse in your directive you need to provide a scope (context) to parse against. Since you're using an isolated scope the value of product.id will be on the directive's parent's scope- so we'll use scope.$parent.

Here's an example:

 myApp.directive('widget', function ($parse) {
    return {
        restrict: "E",
        scope: {
            productId: '@'
        },
        link: function(scope, element, attr) {          
               nvalue = $parse(scope.productId)(scope.$parent);
               console.log("parse result",nvalue);
        }         
    };
});

demo fiddle

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

1 Comment

thank you for the clear explanation of using $parse. I didn't understand the documentation of passing scope in.
0

I'm afraid there is no binding that fits your need, you can try this:

link:function(scope, element, attr){
          scope.productId = scope.$parent.$eval(attr.productid);
}

But this approach is not recommended

DEMO

The recommended approach is using @ binding and {{}} in your html

  scope:{
    productId: '@'
  }

Your HTML:

<widget product-id="{{productId}}"></widget>

DEMO

Comments

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.