3
votes

I have hit a head scratcher! It seems like a fairly simple issue... I am using the ui-grid angular control and I'm attempting to use a custom directive in the cellTemplate. I can succesfully get it in there, but the problem is I am not able to bind correctly to the directive. I can bind properties but not functions from the parent. When I try to access a parent function which has been bound I get an object not defined error.

As far as I know I setup binding and cell template correctly:

//in columndefs:
{
        name: 'item', displayName: 'Status',
        width: 200, cellTemplate: '<dropdowncss item="row.entity[col.field]" do-drop="dropdowncombo"></dropdowncss>'
},

//directive declaration:
app.directive('dropdowncss', function () {
    return {
        restrict: 'E',
        scope:
            {
                item: '=',
                doDrop: '&'
            },
        controller: 'DropDownCSSCtrl',
        templateUrl: 'dropdowncss.html'
    };

When you click on one of the colored drop downs it should alert 'success' Please see the simple plunker here:

http://plnkr.co/edit/HuuxxgV1GoWzfWlUvafw?p=preview

Any help would be appreciated. Thanks!

3

3 Answers

5
votes

So from the scope that the cellTemplate gets compiled, you are many miles deep in scopes and your function dropdowncombo does not exist. That is why you get undefined. From that scope, Your dropdowncombo function is actually $parent.$parent.$parent.$parent.$parent.$parent.dropdowncombo. Now I would never suggest you use that so you should engineer an alternate way to pass you scoped function from that cell template.

To view your plunker working, change line 20 of app.js to

width: 200, cellTemplate: '<dropdowncss item="row.entity[col.field]" do-drop="$parent.$parent.$parent.$parent.$parent.$parent.dropdowncombo"></dropdowncss>'

I would make the edit for you, but it's just too embarrassing to have that many $parents even in this modern age of acceptance.

So there are a few ways to fix this but here's my take. Save the function from your scope that you want to execute in the column definition and then call that using col.colDef.func

Updated column definition in app.js is as follows:

{
     name: 'item', displayName: 'Status',
     handleClick: $scope.dropdowncombo, 
     width: 200,  
     cellTemplate: '<dropdowncss item="row.entity[col.field]" do-drop="col.colDef.handleClick"></dropdowncss>'
}

Here's an edited working plunker

4
votes

This question is Old but I have a better approach - you can use grid.appScope to access current $scope. so change you line 20 in app.js to - width: 200, cellTemplate: '<dropdowncss item="row.entity[col.field]" do-drop="grid.appScope.dropdowncombo"></dropdowncss>'

working Plunker is here - http://plnkr.co/edit/5LiETuG2PEOJhvEcFypF?p=preview

0
votes

In case anyone else was curious I also found the method using events. $emit can be used to broadcast an event up the whole parent scope hierarchy. So the following worked:

Adding this to the parent scope:

  $scope.$on('EventDropDown', function () {
      alert('passed up the event successfully');
  });

And calling it from the directive like this:

<div class="divDropDown" ng-click="$emit('EventDropDown')">

That passed it up to the parent scope correctly. In contrast to $emit, $broadcast sends events down the scope hierarchy (not applicable in this scenario). There is no other hooking up things other than the event name. That makes it kind of convenient.