1

I'm trying to use an Angular directive to create a form where the user can specify the number of children and, for each child, an edit box appears allowing the childs date of birth to be entered.

Here's my HTML:

<div ng-app>
  <div ng-controller="KidCtrl">
    <form>
    How many children:<input ng-model="numChildren" ng-change="onChange()"/><br/>
    <ul>
        <li ng-repeat="child in children">
            <child-dob></child-dob>
        </li>
      </ul>
    </form>
  </div>
</div>

Here's the JS:

var app=angular.module('myApp', []);

function KidCtrl($scope) {
  $scope.numChildren = 2
  $scope.children = [{dob: "1/1/90"}, {dob: "1/1/95"}];
  $scope.onChange = function () {
    $scope.children.length = $scope.numChildren;
  }
}

app.directive('childDob', function() {
    return {
      restrict: 'E',
      template: 'Child {{$index+1}} - date of birth: <input ng-model="child.dob" required/>'
    };
  });

And here's a jsFiddle

The problem is that it's just not working. If I enter 1 in the numChildren field then it shows 1 bullet point for the list element but it doesn't show any of the HTML. If I enter 2 in the numChildren field then it doesn't show any list elements.

Can anyone explain what I'm doing wrong?

Many thanks ...

1 Answer 1

1

Your main issue is that the directive childDOB is never rendered. Even though your controller works because 1.2.x version of angular has global controller discover on. It will look for any public constructors in the global scope to match the controller name in the ng-controller directive. It does not happen for directive. So the absence of ng-app="appname" there is no way the directive gets rendered. So add the appname ng-app="myApp" and see it working. It is also a good practice not to pollute global scope and register controller properly with controller() constructor. (Global look up has anyways been deprecated as of 1.3.x and can only be turned off at global level.)

You would also need to add track by in ng-repeat due to the repeater that can occur due to increasing the length of the array based on textbox value. It can result in multiple array values to be undefined resulting in duplicate. SO:-

 ng-repeat="child in children track by $index"

Fiddle

Html

<div ng-app="myApp">
    <div ng-controller="KidCtrl">
        <form>How many children:
            <input ng-model="numChildren" ng-change="onChange()" />
            <br/>
            <ul>
                <li ng-repeat="child in children track by $index">{{$index}}
                    <child-dob></child-dob>
                </li>
            </ul>
        </form>
    </div>
</div>

Script

(function () {

    var app = angular.module('myApp', []);

    app.controller('KidCtrl', KidCtrl);

    KidCtrl.$inject = ['$scope'];
    function KidCtrl($scope) {
        $scope.numChildren = 2
        $scope.children = [{
            dob: "1/1/1990"
        }, {
            dob: "1/1/1995"
        }];
        $scope.onChange = function () {
            $scope.children.length = $scope.numChildren;
        }
    }

    app.directive('childDob', function () {
        return {
            restrict: 'E',
            template: 'Child {{$index+1}} - date of birth: <input ng-model="child.dob" required/>'
        }
    });
})();
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a million - my problem just went away and I learned useful things in the process!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.