nj51 nj51 - 3 months ago 8
AngularJS Question

Dynamically added directive but content not showing

I am new to angular and am trying to create a voting poll app. Right now I have 4 input boxes. 1 question and 3 answers to use when creating a new poll. I also have a button that adds a new input box if you want to add another answer. I read if I want to dynamically at content to the DOM I should use a directive. I created one that adds the new html content I want that should also add a ng-model attribute so I can access the content that is in an array along with the other content. The input boxes that were originally there work fine but when I add a new one it won't access it.

Directive/function code:

votingApp.directive('addAnswers', [function(){

return {
template:"<li><input type='text' ng-model='choices[3]' /></li>",
restrict: 'E'
}
}]);


Function that would add the new directive into the list of input boxes.

$scope.addAnswer = function(){

var node = document.createElement("LI");



var textnode = document.createElement("add-answers");
node.appendChild(textnode);

$scope.pollAnswers.appendChild(node);



};


Lastly where the it should be added to in the HTML.

<form ng-submit="createPoll()">
<p>Question</p>
<input type="text" ng-model="pollQuestion" />

<p>Answers</p>
<ul id="answers">
<li><input type="text" placeholder=" " ng-model="choices[0]" /></li>
<li><input type="text" placeholder=" " ng-model="choices[1]" /></li>
<li><input type="text" placeholder=" " ng-model="choices[2]" /> </li>
</ul>
<input id="create" type="submit" value="Create Poll" />
</form>


Basically as I add a new input I am going to make the ng-model = to the length of the array. However, when I do this the array doesn't get a slot bigger when adding a new element.

Answer

Here's a plunk with a better example: http://plnkr.co/edit/gSWHCxgagMrF4OoEZDh1?p=preview

You could just ng-repeat based on your choices.

// controller
votingApp.controller('Controller', ['$scope', function($scope) {
    $scope.choices = [];

    $scope.addAnswer = function() {
        $scope.choices.push('');
    };
}]);

// html
<ul id="answers">
    <li ng-repeat="answer in choices track by $index">
        <input type="text" ng-model="choices[$index]" />
    </li>
</ul>

Here's some stuff from my plunk so it's easier to see:

votingApp.directive('answers', function() {
    return {
      restrict: 'E',
      scope: {
          choices: '='
      },
      template: '<li ng-repeat="answer in choices track by $index"><input type="text" ng-model="choices[$index]" /></li>'
    };
});

votingApp.controller('VotingController', [ 
  '$scope',
  function($scope) {
    $scope.choices = [];

    // if you want to start with some choices use this
    // $scope.choices = new Array(3);

    $scope.addAnswer = function() {
      $scope.choices.push('');
    };
  }
]);

<body ng-app="votingApp" ng-controller="VotingController">
    <ul>
      <answers choices="choices"></answers>
    </ul>
    <button ng-click="addAnswer()">Add Answer</button>
</body>