3
\$\begingroup\$

All, I barely have a week of angular behind me and I am still struggling with some of the concepts. Below is a piece of code I came up with. The idea is to let the user add/delete entries in a model (in practice, the model is read from a json and is more complex than what is presented). While this code seems to work, I'm wondering whether it's "proper" angular:

  • Is it OK to leave the add_item function in the controller ? I understand that any DOM manipulation should be put in a directive, but it's only manipulating the model, right?
  • Shouldn't the del_item be in the controller too, then?
  • Using the index to control which item to delete look a bit dangerous, what would be a better alternative?

Thanks for any input.

<html ng-app="main">

  <head >
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
  </head>

 <body>

 <div ng-controller="BaseController">
   {{items}}
   <div>
     <button type="button" ng-click="add_item()">
       New item
     </button>
   </div>
   <ul>
     <li ng-repeat="i in items">
       <display-item idx={{$index}}></display-item>
     </li>
   </ul>
 </div>

<script>
  angular.module("main", [])
  .controller("BaseController",
    function($scope){
      $scope.items = [{key:1, a:'A'},{key:2, a:'B'},{key:3, a:'C'}];
      $scope.last = $scope.items.length;
      $scope.add_item = function() {
        var item={key: $scope.last + 1, a:'?'};
        $scope.items.push(item);
        $scope.last += 1;
        };
    }
   )
  .directive('displayItem',
    function() {
    return {
      restrict: 'E',
      transclude: true,
      scope: {idx: '@'},
      template: '<strong>{{idx}}:</strong>'+
                '{{$parent.items[idx].key}}={{$parent.items[idx].a}}'+
                '<button ng-click="del_item(idx)">X</button>',
      link: function(scope, element, attrs) {
        scope.del_item=function(i){
          scope.$parent.items.splice(i,1)}
        }
      }
    }
  );
</script>

\$\endgroup\$
2
+50
\$\begingroup\$
  • Right, you're only manipulating the model, updating the model about a change (thus) updating it in the controller is perfectly fine, and it's what the controller does.

  • del_item should be in the controller too, you are correct. That's where it belongs.

  • Using the index to deleting the item is dangerous, what I'd do is pass this as a function and then use an indexOf to locate the element you're deleting and delete that.

If I may ask, why are your display items in a directive in the first place and not in the DOM? You could use an ng-repeat in the DOM to repeat the items instead and drop the directive altogether.

Directives are useful for code reuse, are you reusing this spefici component in a lot of other places through out your code? Behaviors affecting your models and not just your presentation logic should probably not be in the directive to begin with (like del_item in your example), a directive should encompass presentational behavior and not business logic.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks a lot for the feedback. As I had mentioned, I'm still very new to Angular, but the concepts are slowly sinking in... \$\endgroup\$
    – Pierre GM
    Jun 27 '13 at 14:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.