Skip to content Skip to sidebar Skip to footer

Isolated Scope For Items Inside Ng Repeat In Directive Template

I'm trying to create a directive where in data is displayed in a table layout. Each row has a edit button and on clicking the edit button only that row should be in edit mode. But

Solution 1:

 angular
    .module('myApp', [])
    .controller('myCtrl', ['$scope', function($scope) {
        $scope.employees = [{
            'FirstName': 'Jay',
            'LastName': 'Raj',
            'Email': 'jay3dec@gmail.com'
        }, {
            'FirstName': 'Roy',
            'LastName': 'Mathews',
            'Email': 'roymathews@gmail.com'
        }];
        $scope.employees.forEach(function(employee) {
            employee.isEdit = false;
        });
    }])
    .directive('myGrid', function() {
        return {
            restrict: 'E',
            scope: {
                employees: '='
            },
            controller: function($scope) {
                $scope.showEdit = function(emp) {
                    emp.isEdit = !emp.isEdit;
                };
            },
            template: '<table class="table">' +
                '<thead>' +
                '<tr>' +
                '<th ng-repeat="(key,value) in employees[0]">{{key}}</th>' +
                '</tr>' +
                '</thead>' +
                '<tbody>' +
                '<tr ng-repeat="emp in employees">' +
                '<td><span ng-if="!emp.isEdit">{{emp.FirstName}}</span><input type="text" ng-if="emp.isEdit" ng-model="emp.FirstName" class="form-control"></td>' +
                '<td><span ng-if="!emp.isEdit">{{emp.LastName}}</span><input type="text" ng-if="emp.isEdit" ng-model="emp.LastName" class="form-control"></td>' +
                '<td><span ng-if="!emp.isEdit">{{emp.Email}}</span><input type="text" ng-if="emp.isEdit" ng-model="emp.Email" class="form-control"></td>' +
                '<td><span ng-click="showEdit(emp)" ng-class="{\'glyphicon glyphicon-edit\':emp.isEdit==false,\'glyphicon glyphicon-ok\':emp.isEdit==true}"></span></td>' +
                '</tr>' +
                '</tbody>' +
                '</table>'
        };
    });
<linkrel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"crossorigin="anonymous"><scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><bodyng-app="myApp"><divclass="container"ng-controller="myCtrl"><my-gridemployees="employees"></my-grid></div></body>

Solution 2:

Yosvel solution is fine and is admittedly the simplest.

Nevertheless, I created an alternative based on the $index of the ng-repeat. One could also keep track of which item is being modified instead of the $index.

Demo

angular.module('myApp', [])

.controller('myCtrl', ['$scope', function($scope) {
  $scope.employees = [{
    'FirstName': 'Jay',
    'LastName': 'Raj',
    'Email': 'jay3dec@gmail.com'
  }, {
    'FirstName': 'Roy',
    'LastName': 'Mathews',
    'Email': 'roymathews@gmail.com'
  }];
}])

.directive('myGrid', function() {
  return {
    restrict: 'E',
    scope: {
      employees: '='
    },
    controller: function($scope) {

      $scope.indexBeingEdited = -1;

      $scope.showEdit = function($index) {
        if($scope.indexBeingEdited === $index) {
          // second click... stop edit 
          $scope.indexBeingEdited = -1;
          return;
        }
        $scope.indexBeingEdited = $index;
      };
      $scope.isEdit = function($index) {
        return$index === $scope.indexBeingEdited;
      };
    },
    templateUrl: '/myGrid.html'
  };
})

<body ng-app="myApp">
  <div class="container" ng-controller="myCtrl">
    <my-grid employees="employees"></my-grid>
  </div>
</body>


<script type="text/ng-template"id="/myGrid.html">
  <table class="table">
    <thead>
      <tr>
        <th ng-repeat="(key,value) in employees[0]">{{key}}</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="emp in employees">
        <td>
          <span ng-hide="isEdit($index)">{{emp.FirstName}}</span>
          <input type="text" ng-show="isEdit($index)" ng-model="emp.FirstName" class="form-control">
        </td>
        <td>
          <span ng-hide="isEdit($index)">{{emp.LastName}}</span>
          <input type="text" ng-show="isEdit($index)" ng-model="emp.LastName" class="form-control">
        </td>
        <td>
          <span ng-hide="isEdit($index)">{{emp.Email}}</span>
          <input type="text" ng-show="isEdit($index)" ng-model="emp.Email" class="form-control">
        </td>
        <td>
          <span ng-click="showEdit($index)" class="glyphicon" ng-class="{' glyphicon-edit':isEdit($index)===false,'glyphicon-ok':isEdit($index)===true}"></span>
        </td>
      </tr>
    </tbody>
  </table>
</script>

Solution 3:

try like this

angular.module('myApp', [])

.controller('myCtrl', ['$scope', function($scope) {
  $scope.employees = [{
    'FirstName': 'Jay',
    'LastName': 'Raj',
    'Email': 'jay3dec@gmail.com'
  }, {
    'FirstName': 'Roy',
    'LastName': 'Mathews',
    'Email': 'roymathews@gmail.com'
  }];
}])

.directive('myGrid', function() {
  return {
    restrict: 'E',
    scope: {
      employees: '='
    },
    controller: function($scope) {
      $scope.isEdit = -1;

      $scope.showEdit = function(index) {
       
       $scope.isEdit = $scope.isEdit == index ? -1 : index;
      }
    },
    template: '<table class="table">' +
      '<thead>' +
      '<tr>' +
      '<th ng-repeat="(key,value) in employees[0]">{{key}}</th>' +
      '</tr>' +
      '</thead>' +
      '<tbody>' +
      '<tr ng-repeat="emp in employees">' +
      '<td><span ng-show="isEdit != $index">{{emp.FirstName}}</span><input type="text" ng-show="isEdit == $index" ng-model="emp.FirstName" class="form-control"></td>' +
      '<td><span ng-show="isEdit != $index">{{emp.LastName}}</span><input type="text" ng-show="isEdit == $index" ng-model="emp.LastName" class="form-control"></td>' +
      '<td><span ng-show="isEdit != $index">{{emp.Email}}</span><input type="text" ng-show="isEdit == $index" ng-model="emp.Email" class="form-control"></td>' +
      '<td><span ng-click="showEdit($index)" ng-class="{\'glyphicon glyphicon-edit\':isEdit != $index,\'glyphicon glyphicon-ok\':isEdit == $index}"></span></td>' +
      '</tr>' +
      '</tbody>' +
      '</table>'
  };
})
<linkrel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"crossorigin="anonymous"><scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><divng-app="myApp"><divclass="container"ng-controller="myCtrl"><my-gridemployees="employees"></my-grid></div></div>

Post a Comment for "Isolated Scope For Items Inside Ng Repeat In Directive Template"