Brad W
Brad W

Reputation: 2558

AngularJS : Why does the first binding I pass into my directive show the variable and not the value

The first {{labelText}} binding I pass to my directive shows up in the view as {{labelText}} when the (+) increment button is clicked. Even though the AngularJS properties in my Chrome inspector show its value as "Enter a name to identify each resource". Subsequent clicks on the increment button show input fields get appended with the correct value for LabelText.(See screenshot below)

enter image description here

Here is my controller

.controller('CounterCtrl', function($scope) {

'use strict';
angular.module('Carrepair2.controllers', ['ionic', 'ui.bootstrap', 'Carrepair2.directives.addinputs', 'Carrepair2.directives.removeinputs'])
  $scope.decrement = function() {
    $scope.count = $scope.count - 1;
    if ($scope.count < 0){
      $scope.count = 0;
    }
  };
  $scope.increment = function() {
    $scope.count = $scope.count + 1;
  };

  $scope.labelText = 'Enter a name to identify each resource';
})

Here is my directive

'use strict';
angular.module('Carrepair2.directives.addinputs', ['ionic', 'ui.bootstrap'])
.directive('addinputs', function($compile){
  return function(scope, element){
    element.bind('click', function(){
      var childId = 'space-for-inputs' + scope.$index;
      var inputLabelForId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
        return v.toString(16);
            });
      angular.element(document.getElementById(childId)).append(
        $compile('<div class=\'resource-name-input input_wrapper\'><input type=\'text\' id="' + inputLabelForId  + '" required><label for="' + inputLabelForId +'">{{labelText}}</label></div>')(scope));
    });
  };
});

and this is my template

<ul class="list">
    <li class="item" id="resource{{$index}}" ng-repeat="resource in resources">
        <div class="resource-desc">{{resource.description}}</div>
        <img ng-src="{{resource.thumb}}">
        <div class="incrementer" ng-controller="CounterCtrl">
            <button class="count-btn ion-arrow-up-b"  ng-click="increment()" ng-init="count=0" addinputs>
                <span class="ion-plus-round"></span>
            </button>
            <div class="count-btn count">{{count}}</div>
            <button class="ion-arrow-down-b"  ng-click="decrement()" removeinputs>
                <span class="ion-minus-round"></span>
            </button>
        </div>
        <div id='space-for-inputs{{$index}}'></div>
    </li>
</ul>

Sorry the link in the jsFiddle in the comments doesn't work. Here is a link to the jsFiddle replicating the problem. http://jsfiddle.net/KyEr3/106/

Upvotes: 1

Views: 413

Answers (1)

Mathew Berg
Mathew Berg

Reputation: 28750

I highly recommend you go read up on how to use angularjs, a lot of what I've seen in your fiddle seems off. Continuously having to $compile should not be something you're starting out with. In either case the issue comes down with how you wired up your element click. When something happens outside of angulars knowledge i.e. this line:

element.bind('click', function(){

You have to let angular know to update, so that function will become:

element.bind('click', function(){
  angular.element(document.getElementById("space-for-inputs")).append(
    $compile('<div class=\'resource-name-input input_wrapper\'><input type=\'text\' id=\'myinput\' required><label for=\'myinput\'>{{labelText}}</label></div>')(scope));
    scope.$apply();
});

But still, you should be using an ng-click. Here is your updated fiddle with it working: http://jsfiddle.net/5ThTT/

Upvotes: 0

Related Questions