0

I have an Angular JS app that is communicating with a REST API. The app has an admin part that let a user create, read, update and delete a resource.

There's several different resources, one partial per resource where I define each member as an input field of some sort. I have created a directive that creates a two way binding for whats common for the templates.

I have also created a ngResource for each of my resources.

Now to my problem. I have the controller for one resource working, and it mostly contains just functions that are called directly from the partials (e.g submit() ), and communicates with the ngResource.

The code itself can, with a few exceptions, be copied to all of the other controllers and just change the resource name. This is what I want to avoid.

How can I create an abstract ParentCtrl and somehow inject the resource I need at that time? Is this testable? Is this a bad approach of the problem?

Normally I would have tried to abstract a model instead of a controller, but I can't really see how in this case.

Edit: Added code

Resource:

angular.module('experienceServices', ['ngResource'])
  .factory('Experience', function($resource){
    return $resource('/api/experience/:id',
      {'id': '@_id'}, {edit: { method: 'PUT' }});
  });

Controller:

App.controller('ExperienceCtrl', function( $scope, Experience ) {
  $scope.resources = [];
  $scope.currentItem = {};

  $scope.updateResources = function(){
    $scope.resources = Experience.query();
  };

  $scope.findById = function(id){
    for (var i = 0; i < $scope.resources.length; i++){
      if ($scope.resources[i]._id === id){
        return $scope.resources[i];
      }
    }
  };

  $scope.showItem = function(id){
    $scope.currentItem = findById(id);
  };

  $scope.create = function (experience){
    Experience.save(angular.copy(experience), function(){
      $scope.updateResources();
    });
  };

  $scope.editItem = function (experience){
    var item = angular.copy(experience);
    if (!item.hasOwnProperty('_id')){
      alert('Can not modify non existing item');
    }
    Experience.edit(item, function(res){
      $scope.updateResources();
    });
  };

  $scope.edit = function(id){
    $scope.experience = $scope.findById(id);
  };

  $scope.del = function(id){
    Experience.remove({ id: id }, function(){
      $scope.updateResources();
    });
  };
  $scope.updateResources();
});

Directive:

App.directive('resources', function (){
    return {
      scope: {
        list: '=',
        display: '@',
        edit: '&',
        del: '&'
      },
      template: '<div ng-repeat="elem in list">Name: {{ elem[display] }}' +
                ' <button ng-click="edit({ item: elem._id })">Edit</button> ' +
                ' <button ng-click="del({ item: elem._id })">Delete</button> ' +
                '</div>'
    };
  });
1
  • Can you post some code? This kind of question will be better answered in the specific instead of in the abstract. Commented Feb 10, 2013 at 20:47

1 Answer 1

1

what about wrapping your entire API to a service and accessing it from the controllers ? you can pass the resource type as an argument to the functions

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

1 Comment

You are absolutely right. A service is actually the "model", and if I put all of my methods in a service, export it as an object and just pass the type to the service. That way the service is re-usable and not the controller. Thanks for giving me the push I needed to figure this out.

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.