Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting $scope variables from a directive

The directive in question is this guy here: Dynamic template in directive based on attributes?

Anyway, here's what I'm trying to accomplish.

This <titlebar> directive can take an attribute called edit-button. If this exists, and when the button is clicked, I'd like to set a $scope variable in my controllers that will toggle the visibility of buttons to delete/edit an item.

For example, if I set $scope.currentlyEditting = true; in my directive, I'd tie this to the controller, and then use ng-show to show/hide the controls. I'm just not sure how to get that data into my controller.

titleBar directive:

robus.directive("titlebar", function() {
  return {
    restrict: "E",
    template: "<header class='bar-title' ng-class='{\"sub-view\": view}'>"+
              "<a class='button' ng-click='goBack()' ng-show='back'><i class='icon-arrow-left'></i> Back</a>" +
              "<h1 class='title' ng-transclude>" +
              "<span class='sub-title' ng-show='view'>{{view}}</span></h1>" +
              "<a class='button' ng-click='showEdit()' ng-show='edit'>Edit</a>" +
              "</header>",
    scope: {
      view: '@view',
      edit: '@editButton',
      back: '@backButton'
    },
    transclude: true,
    replace: true,
    link: function ($scope, $element, attrs, ctrl) {
      // $scope.$apply();
    },
    controller: function($scope, $element, $attrs, $location, $routeParams) {
      /* simple back button implementation */
      $scope.goBack = function() {
        history.back(-1)
      }

      // $scope.showEdit = function() {
      //   $scope.currentlyEditting = true;
      // }
    }
  }
});
like image 466
dmackerman Avatar asked Jun 28 '13 21:06

dmackerman


2 Answers

You have several options for accomplishing this.

Instead of creating an isolation scope you could use $scope.$eval(attrs.editButton) (or view, or backButton) to process the attributes from the directive. Then you could set variables and call functions in whichever scope you were working in.

If you want to continue using the isolation scope you could also pass in a function using & which could toggle the edit mode.

This would be done like so:

// In the directive
template: '...<a href="" ng-click="toggleEdit()">Edit</a>...',
scope: {
  ...
  toggleEdit: '&',
  ...
}

// In the HTML (or directive template)
<titlebar ... toggle-edit="toggleEditMode()" ...>...</titlebar>

// In the controller (ngController, not directive controller)
$scope.toggleEditMode = function() {
  $scope.editMode = !$scope.editMode;
}

Lastly, you could also use $scope.$parent to access the parent scope from the isolation scope in the directive. I don't recommend this because it creates a tight coupling between the directive and your controller, but it is an option.

like image 188
rtcherry Avatar answered Sep 19 '22 11:09

rtcherry


I assume you want to pass it back up to the parent controller. In your scope attribute, you use the "@" binding which is one way. You can use "=" to bind two ways. I made a Plunker to show this: http://plnkr.co/edit/HBPcsT?p=preview

Just in case you need to keep it inside the directive, I showed an example of that as well.

like image 33
John Tseng Avatar answered Sep 22 '22 11:09

John Tseng