Reputation: 683
This question follows on a previous question I had about getting these directives to work:
Previous question about dynamically generating a grid
My Html looks like this:
<div ng-grid ng-collection="entries" ng-collection-headings="headings" ng-button-click="theAction(inp)">
<div ng-checkbox-column></div>
</div>
It generates Html that looks like this:
<div ng-grid="" ng-collection="entries" ng-collection-headings="headings" ng-button-click="theAction(inp)" class="ng-isolate-scope">
<table class="table table-bordered">
<thead>
//Truncated for brevity
</thead>
<tbody>
<tr id="item0" ng-repeat="item in ngCollection" class="ng-scope">
<td ng-checkbox-column="">
<label>
<input type="checkbox" ng-model="item.checked" ng-click="tempButtonClicked()" class="ng-pristine ng-untouched ng-valid"> From the checkbox directive.
</label>
</td>
</tr>
//Truncated for brevity
</tbody>
</table>
</div>
The problem I am having is that the ng-click events of the ng-checkbox-column directive cannot be assigned from the myCtrl controller outside of the ng-grid directive. This is because I created an isolate scope for the ng-grid directive and the ng-checkbox-column directive is sharing the scope of the ng-grid directive.
Is there a way around this?
What options do I have to get this to work?
Is my only option to use events?
The reason I created an isolate scope for the ng-grid directive is so that it can be used more than once in the same controller. Therefore I cannot share the scope of the myCtrl controller.
Here is a plunker showing the problem:
Plunker with working dynamic grid, but limited ng-click
Looking at the plunker, you can click on the buttons to see where the click happens in relation to the "scopes". I would like the checkboxes to fire their own events and update that status without having to go through the ng-grid directive.
Currently I am handling the ng-click with this:
ng-click='tempButtonClicked()'
and in the ng-checkbox-column controller:
$scope.tempButtonClicked = function () {
var val = "From the checkbox directive";
$scope.buttonClicked(val);
};
where $scope.buttonClicked(val); is a reference to a function defined in the controller of the ng-grid directive:
$scope.buttonClicked = function (inp) {
if (typeof inp != 'undefined')
inp = inp + ", through the grid directive.";
else
inp = "From the grid directive.";
$scope.ngButtonClick({ inp: inp });
};
which in turn, binds it to a function specified through an isolate scope variable defined in the ng-grid directive as:
scope: {
ngButtonClick: "&"
},
I hope what I'm explaining makes sense and someone can shed some more light on the subject.
Is a way to bind a function to the ng-checkbox-column directive so that I can call a function in the myCtrl controller when it is clicked.
The reason for this is that I may have multiple column templates in a grid and perform different actions depending on which column is clicked.
With the current way it works, I'll have to define x-amount of functions in the ng-grid directive to use with the templates, which seems like a sloppy way of doing it.
I would LOVE to be able to do this:
<div ng-checkbox-column ng-click-action="someDefinedFunctionInMyCtrl()"></div>
which generates this:
<td ng-checkbox-column="">
<label>
<input type="checkbox" ng-model="item.checked" ng-click="someDefinedFunctionInMyCtrl()"> From the checkbox directive.
</label>
</td>
Upvotes: 0
Views: 824
Reputation: 1933
Got it working using an expression as an attribute and ng-transclude:
http://plnkr.co/edit/3XmsE3d44v8O0AxOoUeF?p=preview
JS:
.directive("ngGrid", function () {
return {
[...]
transclude: true, //added transclude
template: function (element, attrs) {
var children = element.html();
children = children.trim().replace(/div/g, "td");
var htmlText = [
"<input type='button' ng-click='buttonClicked()'",
" value='From the grid directive' />",
"<table class='table table-bordered'>",
"<thead><tr>",
"<th ng-repeat='heading in ngCollectionHeadings'>{{heading}}</th>",
"</tr></thead>",
//added ng-transclude
"<tbody><tr id='item{{$index}}'",
" ng-repeat='item in ngCollection' ng-transclude>",
children,
"</tr></tbody>",
"</table>"
].join('');
return htmlText;
},
[...]
};
})
.directive("ngCheckboxColumn", function () {
return {
restrict: "A",
scope: {
//expression as an attribute
myClick: '&'
},
[...]
controller: function ($scope, $element) {
$scope.tempButtonClicked = function () {
var val = "From the checkbox directive";
//call the expression (val will be available in the expression)
$scope.myClick({val: val});
};
}
};
})
HTML:
<div ng-controller="myCtrl">
<div ng-grid ng-collection="entries"
ng-collection-headings="headings" ng-button-click="theAction(inp)">
<!-- added the my-click expression (use val here) -->
<div ng-checkbox-column my-click="ctrl.theAction(val)"></div>
</div>
<p id="btnClickVal">{{actionVal}}</p>
<input type="button" ng-click="theAction(fromParent)"
value="From the parent controller" />
</div>
Upvotes: 1