0

I have a JSBin here with what I am trying to do. I have a controller and a directive (which are siblings).

The controller I want to keep track of the state of several checkboxes, and the directive I want to populate a div with the checkboxes (in my real application, the directive handles display of about a dozen different templates). The state of the checkboxes is saved in a service that will be accessed again in a different part of the application.

Since I want to maintain the 'controller as' syntax as opposed to just dumping everything into $scope, I am having serious difficulty wrapping my head around having the directive use the controller scope.

Would it be best to move the checkbox toggling code into the directive, or is there some way to include the controller scope into the directive? I have tried playing around with the scope directive option without success.

Edit: Posted code from JSBin here:

HTML:

<!DOCTYPE html>

<html ng-app='MyApp'>

  <head>
    <script src='https://code.angularjs.org/1.3.1/angular.js'></script>
    <script src='http://code.angularjs.org/1.3.1/angular-sanitize.js'></script>
    <script src='data-service.js'></script>
    <script src='my-app.js'></script>
    <script src='my-directives.js'></script>
  </head>

  <body ng-controller='MyController as myCtrl'>
    <div checkbox-template=''></div>
    Checked boxes: <div ng-repeat='checked in data.checkboxes'>{{checked}}</div>
  </body>

</html>

JavaScript:

my-directives.js

dir = angular.module('my-directives', []);

dir.directive('checkboxTemplate', function(){
  return {
    restrict: 'A',
    template: "<ul><li ng-repeat='cb in data.tpl1' ng-bind-html='myCtrl.renderHtml(cb)'></ul>"
  };
});

data-service.js:

dat = angular.module('data-service', []);

dat.service('DataService', function() {
  return {
    checkboxes: [],
    tpl1: [
        "<label><input type='checkbox' value='1' ng-click='boxToggle(1)' ng-checked='data.checkboxes.indexOf(1) > -1'/>Checkbox 1</label>",
        "<label><input type='checkbox' value='2' ng-click='boxToggle(2)' ng-checked='data.checkboxes.indexOf(2) > -1'/>Checkbox 2</label>"
      ]
  };
});

my-app.js:

app = angular.module('MyApp', ['ngSanitize', 'my-directives', 'data-service']);

app.controller('MyController', ['$scope', '$sce', 'DataService', function($scope, $sce, DataService) {
  this.data = DataService;
  self = this;

  this.renderHtml = function(raw_html){
    return $sce.trustAsHtml(raw_html);
  };

  this.boxToggle = function(idx) {
    i = this.data.checkboxes.indexOf(idx);
    alert('Toggling Checkbox');

    if (i > -1) {
      this.data.checkboxes.splice(i,1);
    } else {
      this.data.checkboxes.push(idx);
    }
  };
}]);
wikenator
  • 310
  • 1
  • 4
  • 12
  • You could do something like this http://jsfiddle.net/bgr1ofyo/. Ref: http://stackoverflow.com/questions/17417607/angular-ng-bind-html-unsafe-and-directive-within-it. – themyth92 Nov 16 '14 at 08:24
  • great solution! works the way i was trying to get it to. – wikenator Nov 19 '14 at 21:31

1 Answers1

0

You want to use the & scope option within your directive to allow it to invoke functions defined in the parent scope.

user2943490
  • 6,900
  • 2
  • 22
  • 38
  • Once I include the `scope` option in my directive, the checkboxes are no longer displayed. I've tried adding `require: '^ngController'` and `scope: { data: '=' }` in the `checkboxTemplate` directive, but I'm still not sure how to get the directive to share the `MyController` scope. – wikenator Nov 14 '14 at 18:07