Reputation: 2564
I have a directive for a javascript grid library slickgrid.
http://plnkr.co/edit/KWZ9i767ycz49hZZGswB?p=preview
What I want to do is pass the selected row back up the controller. So I want to use isolated scope (using the '=') to get two-way binding working between the controller and directive.
Everything works if I define the directive without any sort of scope declaration:
<slickgrid id="myGrid" data="names" selected-item="selectedItem"></slickgrid>
app.directive('slickgrid', function() {
return {
restrict: 'E',
replace: true,
//scope: {
// selectedItem: '='
//},
template: '<div></div>',
link: function($scope, element, attrs) {
...
var redraw = function(newScopeData) {
grid.setData(newScopeData);
grid.render();
};
$scope.$watch(attrs.data, redraw, true);
But if I uncomment the lines above (lines 19-21 in app.js) it looks like the $scope.$watch which is watching the attrs.data object is calling redraw but the attrs.data is being passed in as undefined.
My analysis could be wrong, but I'm not sure why defining the scope would cause this. Can someone explain why that might be?
.nathan.
Upvotes: 1
Views: 288
Reputation: 364677
If you define an isolate scope, then any $watch in your directive will be looking for whatever attrs.data
evaluates to on your isolate scope. attrs.data
evaluates to the string names
, so the $watch is looking for $scope.names
on your isolate scope, which doesn't exist. (Without the isolate scope, the directive uses the same scope as MainCtrl, and $scope.names
exists there.)
To use an isolate scope, you'll need to define another isolate scope property to pass in names
:
scope: {
selectedItem: '=',
data: '='
},
...
$scope.$watch('data', redraw, true);
The HTML can remain the same.
Upvotes: 1