2

I have a isolate scope directive that I am using inside ng-repeat, which is iterating over an array from the controller of that template. The template is as follows:

<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="bootstrap.min.css" />
    <script src="angular.min.js"></script>
    <script src="script1.js"></script>
  </head>

  <body ng-app="AddNewTest" ng-controller="AddNewController">
    <div class="items" ng-repeat="row in rows">
      <add-new-row data="row" index="$index"></add-new-row>
    </div>
  </body>

</html>

The directive is defined as follows:

angular.module('AddNewTest', []).
directive('addNewRow', function ($timeout) {
  return {
    controller: 'AddNewController',
    link: function (scope, element, attribute) {
      element.on('keyup', function(event){
        if(scope.index + 1 == scope.rows.length) {
          console.log('keyup happening');
          $timeout(function () {
            scope.rows.push({ value: '' });
            scope.$apply();
          });
        }
      })
    },
    restrict: 'E',
    replace: true,
    scope: {
      index: '='
    },
    template: '<div class="add-new"><input type="text" placeholder="{{index}}" ng-model="value" /></div>'
  }
}).
controller('AddNewController', function ($scope, $timeout) {
  $scope.rows = [
    { value: '' }
  ];
});

But even after adding new row and doing a $apply() the ng-repeat is not rendering the new data added. Please help.

Plnkr Link Here

3
  • 1
    You have isolate scope in directive. Pass array of rows in directive. Like this scope: { index: '=', rows:"=" }.Don't create rows in controller AddNewController. Remove $scope.rows = [ { value: '' } ]. Commented Aug 29, 2016 at 12:52
  • How do you want this to work? An input for each value? Only 1 input that is used to push into the array? What result do you expect? Commented Aug 29, 2016 at 14:19
  • @gyc I would like to add new row on keyup event in the last row. Commented Aug 30, 2016 at 9:41

2 Answers 2

1

Pass array of rows to directive as follow:-

 scope: {
  index: '=',
  rows :'='
},

<add-new-row rows="rows"  index="$index"></add-new-row>

Working plunker

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the help. Removing the controller from directive defination helped update of ng-repeat on row update.
1

Each ng-repeat creates an isolated scope than you declare an isolated scope inside your directive that has the same controller as the div. You're swimming in the $scope soup :)

I would personnally make a clean and independent directive with its own controller.

angular.module('AddNewTest', []).
directive('addNewRow', function () {
  return {
    restrict: 'E',
    controller: MyController,
    controllerAs: '$ctrl',
    template: '{{$ctrl.rows.length}}<div class="add-new"><pre>{{$ctrl.rows | json}}</pre><input type="text" placeholder="0" ng-model="value" /></div>'
  }
}).
controller('MyController', MyController);

function MyController($scope) {
  var vm = this;
  this.rows = [ { value: '' } ];

   $scope.$watch("value",function(value){
     if(value)
      vm.rows.push({ value: value });
   });
}

http://plnkr.co/edit/AvjXWWKMz0RKSwvYNt6a?p=preview

Of course you can still bind some data to the directive using bindToController (instead of scope:{}) and if you need an ng-repeat, do it in the directive template directly.

1 Comment

Yeah. My bad. I use seperate controller for each directive i create. But this time i messed up trying to reuse the same as for the global template as.

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.