1

I have a directive called styledCheckbox. It looks like this:

directive('styledCheckbox', function($timeout){
    return {
      restrict: 'A',
      templateUrl: 'checkbox.html',
      replace:true,
      transclude: 'element',
      scope:false
    };
});

It's very simple. It takes an input element and inserts it into some preformed HTML.

<span class="checkbox">
  <ng-transclude></ng-transclude>
  <div class="checkbox-overlay">
    <div class="checkbox-overlay-inner-content">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 19">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9.3 11.14L20.26 0 24 3.86 9.27 19 0 9.53l3.81-3.9z"></path>
      </svg>
    </div>
  </div>
</span>

So, my index.html file looks like this:

<body ng-controller="test">
  <input styled-checkbox name="{{option.name}}" ng-model="option.value" type="checkbox"/>
</body>

And becomes...

<span class="checkbox">
  <ng-transclude>
    <input styled-checkbox name="{{option.name}}" ng-model="option.value" type="checkbox"/>
  </ng-transclude>
  <div class="checkbox-overlay">
    <div class="checkbox-overlay-inner-content">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 19">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9.3 11.14L20.26 0 24 3.86 9.27 19 0 9.53l3.81-3.9z"></path>
      </svg>
    </div>
  </div>
</span>

So great...but here is the problem. When I click that checkbox, the option object within my controller is not updated to reflect that change. It's as though my input element now has its own isolated scope.

Now...here is the odd part. When I switch my directive to do this:

 directive('styledCheckbox', function($timeout){
    return {
      restrict: 'E',
      templateUrl: 'checkbox.html',
      replace:false,
      transclude: true,
      scope:false
    };
});

And change my HTML to this...

<body ng-controller="test">
  <div styled-checkbox>
    <input name="{{option.name}}" ng-model="option.value" type="checkbox"/>
  </div>
</body>

Suddenly everything works just fine. Checking and unchecking my input element is reflected in the controller's scope. So why is this the case and how can I fix it? I've scoured the web high and low and I couldn't find anything detailing this sort of issue.

Zerocaliber
  • 67
  • 1
  • 4

1 Answers1

0

Your issue is that you're using transclude incorrectly in the first instance. 1.) "here's my directive definition"

directive('styledCheckbox', function($timeout){
    return {
      restrict: 'A',
      templateUrl: 'checkbox.html',
      replace:true,
      transclude: 'element',
      scope:false
    };
});

2.) "now put it on the page and transclude it" Transclude takes all elements within the instance of the directive and places them within the tags in the directive definition. Your mistake is that you didn't put any elements in the element so nothing is transcluded correctly.

<input styled-checkbox name="{{option.name}}" ng-model="option.value" type="checkbox"/>

3.) When you move the attribute to an outside div you are saying "place all elements in this div into the element of the "styledCheckbox" directive.

  <div styled-checkbox>
    <input name="{{option.name}}" ng-model="option.value" type="checkbox"/>
  </div>

For further clarification here is a wonderful answer

edit: fixed wonderful answer link

Community
  • 1
  • 1
Patrick Motard
  • 2,650
  • 2
  • 14
  • 23