I am trying to edit an angular directive written by somebody else and I am coming across an issue. It is an attribute directive and I want to watch the value passed in as the attribute's value for changes.
This works when I give it an isolate scope and watch the property using scope.$watch. However using an isolate scope breaks the directive as it had the scope set to true originally which it needs for other things (as I understand it means it inherits the parent scope).
So my question is, how can I inherit the parent scope, but also watch the attribute's value?
To help clarify, here is a basic example of the directive:
return {
scope: {
myGridsterItem: "=gridsterItem"
},
restrict: 'EA',
controller: 'GridsterItemCtrl',
controllerAs: 'gridsterItem',
require: ['^gridster', 'gridsterItem'],
link: function(scope, $el, attrs, controllers) {
.....
// need to dynamically update draggable/resizable of individuaol gridster item if properties change
scope.$watch("myGridsterItem.draggable", function(newVal) {
draggable.updateDraggable(newVal);
}, true);
scope.$watch("myGridsterItem.resizable", function(newVal) {
resizable.updateResizable(newVal);
}, true);
.....
}
}
This throws an error due to it not inheriting the parent scope. And if I set
scope: true
My error is solved, but the watch handlers never run.
A rough outline of the HTML:
<div gridster="gridsterOpts">
<ul>
<li gridster-item="getPrefs(portlet.id)", ng-repeat="portlet in getPortlets()">
.....
</li>
</ul>
</div>
Please help me, thanks!
Updated answer
I've had more of a play and demonstrated one possible solution in a code snippet below.
Without using an isolated scope (as this caused other issues for you), basically what we need is for
getPrefs(portlet.id)
to get interpolated or parsed when your directive's link function tries to assign it to scope. Without doing this, if you output the value ofattrs.gridsterItem
to console you'll see it'sgetPrefs(portlet.id)
, and not the result of calling that function.The cleanest-looking solution I came across was to use
$parse
. Within your link function, it allows us to evaluate the function contained in the attribute at the time we're assigning it to scope. This way it's the result of that function that gets assigned, which allows the watcher functions to fire correctly.Note that
$parse
has to be added as a dependency to the directive declaration and passed as a parameter.Old Answer:
Within your link function (with non-isolated scope), try this:
attrs
is a param that has been automatically provided to your link function, and should contain within it a collection of the attributes on the element your directive has been used upon. Get the attribute you need, and assign it to a scope variable that matches the relevant ones in the $watch expressions (myGridsterItem
in this case, it looks like).Remember that angular's naming conventions mean that an attribute called
this-is-an-attribute
in the HTML will be accessible asthisIsAnAttribute
(snake- to camel-case conversion) in the javascript.