Creating a generic angularjs listController

2.5k views Asked by At

Angular ui-router allows me to resolve different injections that I can use in my controllers.

I created a simple generic ListController, and in the ui-router I am injecting an object that contains the CRUD functions specific for that particular view, along with the template.

So, for example, let's say I have 2 services with the same "crud" syntax:

addPerson(person, callback){}
deletePerson(person, callback){}
editPerson(person, callback){}
....
addCar(car, callback){}
deleteCar(car, callback){}
editCar(car, callback){}
....

I created a mapping object to map these services' CRUD functions into my generic controller, which is injected through the ui.router.

GenericController:

controller('ListCtrl', ['$scope', 'itemList', 'functions', function ($scope, itemList,   functions) {
    $scope.itemList = itemList;

    $scope.addItem = function(){
        functions.add($scope.item, callback);
    }
    .....
}

router:

        .state('app.people', {
            url: '/people',
            templateUrl: 'views/people.html',
            resolve: {
                    functions: ['People', function(People){
                        return {
                        add: People.createPerson,
                        update: People.updatePerson,
                        delete: People.deletePerson,
                        getItemList: People.getPeopleList
                    }
                    }],
                itemList: ['$q', 'People', function($q, People){
                var deferred = $q.defer();
                    People.getPeopleList(function(resp, status){
                        deferred.resolve(resp);
                    });
                    return deferred.promise;
                }],
                },
            controller: 'GenericController'
        })

So you can use it with the cars too by just injecting a different function mapping in its state definition.

Works like a charm.

But now I would like to be able to use my controller within a div, and not just in a full view. Now here's the problem:

If I use the ng-controller directive, the injector won't know what to provide as either 'itemList' or 'functions' (which is the mapping object), but if I instantiate it through the $controller object, then it won't have its own scope, and I get a

Unknown provider: $scopeProvider <- $scope

because it won't be able to create its own child scope.. I guess I could create a new scope through $rootScope.$new() or something like that, but it feels too much like hacking, and since I'm new to angular, I think that this might be a bad approach for something like this..

Any tips?

1

There are 1 answers

0
XelharK On BEST ANSWER

For future reference, I ended up writing a system of generic controllers, and tiny specialized controllers that extend them.

For the example above, the generic controller is subclassed by both "PeopleController" and "CarController". At the beginning of the controller code, each one of them will do something like:

controller('PeopleController', ['$scope', 'peopleService', function ($scope, peopleService) {
angular.extend(this, $controller('listController', {$scope: $scope, functions:{

        add: peopleService.addPerson,
        remove: peopleService.removePerson,
        [...]

    }}));

    $scope.people = $scope.itemList;

}

So now I can instantiate the controllers on their own even in the ng-controller directive, and they will use the generic controller for all of the CRUD methods.