Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs directive: call method from parent scope within template

I'm pretty new to Angular directives, and I'm having a lot of trouble getting this to do what I want. Here's the basics of what I have:

Controller:

controller('profileCtrl', function($scope) {
  $scope.editing = {
    'section1': false,
    'section2': false
  }
  $scope.updateProfile = function() {};
  $scope.cancelProfile = function() {};
});

Directive:

directive('editButton', function() {
  return {
    restrict: 'E',
    templateUrl: 'editbutton.tpl.html',
    scope: {
      editModel: '=ngEdit'
    }
  };
});

Template (editbutton.tpl.html):

<button
  ng-show="!editModel"
  ng-click="editModel=true"></button>
<button
  ng-show="editModel"
  ng-click="updateProfile(); editModel=false"></button>
<button
  ng-show="editModel"
  ng-click="cancelProfile(); editModel=false"></button>

HTML:

<edit-button ng-edit="editing.section1"></edit-button>

If it's not clear, I want the <edit-button> tag to contain with three different buttons, each interacting with whatever scope property is passed into ng-edit. When clicked, they should change that property then call the appropriate scope method.

The way it is now, clicking the buttons correctly changes the values of $scope.editing, but the updateProfile and cancelProfile methods don't work. I may be way off base on how to use directives properly, but I'm having trouble finding an example online to help me accomplish what I'm trying to do. Any help would be appreciated.

like image 560
Will Durney Avatar asked Jul 01 '14 15:07

Will Durney


1 Answers

One way would be to call the functions using $parent.

<button ng-show="editModel" ng-click="$parent.cancelProfile(); editModel=false">b3</button>

Demo

Another way (and probably the better way), is to configure your directive's isolated scope to contain references to those controller functions:

app.directive('editButton', function() {
  return {
    restrict: 'E',
    templateUrl: 'editbutton.tpl.html',
    scope: {
      editModel: '=ngEdit',
      updateProfile: '&',
      cancelProfile: '&'
    }
  };
});

Then you pass the functions in via HTML:

<edit-button ng-edit="editing.section1" update-profile='updateProfile()' cancel-profile='cancelProfile()'></edit-button>

Demo

like image 89
Jerrad Avatar answered Oct 29 '22 19:10

Jerrad