AngularJS通用列表控制器

时间:2015-07-14 21:28:44

标签: angularjs generics

所以我没有从my last question得到答案,所以我决定自己解决这个问题。

我创建了一个这样的通用控制器:

.controller('GenericListController', function () {

    // Define this
    var self = this;

    // Define our list
    self.list = [];

    // Create our page sizes array
    self.pageSizes = [10, 20, 50, 100];

    // For filtering and sorting the table
    self.pageSize = self.pageSizes[0];
    self.predicate = 'name';
    self.reverse = false;
    self.filter = '';

    // For deleting
    self.delete = function (e, model) {

        // Delete the item
        service.delete(model.id);
    };
});
你可以看到非常简单。 现在我通过将它注入我的控制器中来使用它:

.controller('DashboardController', ['GenericListController', 'CenterService', 'companyId', 'centers', function (Controller, service, companyId, centers) {

    // Assign this to a variable
    var self = Controller;
}])

理论上,分配给 GenericListController 的所有内容现在都可用于 DashboardController 。问题是通用控制器中的行如下所示:

service.delete(model.id);

不知何故,我需要在通用控制器中引用我的服务。我想也许我可以创建一个提供程序并将服务引用注入到构造函数中,但我不确定它是否是单例是一个问题,所以我需要一些帮助。

  1. 服务/工厂/提供商是构建 GenericListController 的好方法吗?
  2. 服务/工厂是否会影响单身?如果是这样,他们可以被创造出来而不是单身吗?
  3. 还有另一种方法可以实现我的目标吗?
  4. 更新1

    所以似乎有些人感到困惑....

    因此,如果我创建了一个如下所示的工厂:

    .factory('ListControllerService', function () {
    
        // Default constructor expecting a service
        return function (service) {
    
            // Define this
            var self = this;
    
            // Define our list
            self.list = [];
    
            // Create our page sizes array
            self.pageSizes = [10, 20, 50, 100];
    
            // For filtering and sorting the table
            self.pageSize = self.pageSizes[0];
            self.predicate = 'name';
            self.reverse = false;
            self.filter = '';
    
            // For deleting
            self.delete = function (e, model) {
    
                // Delete the item
                service.delete(model.id);
            };
        };
    })
    

    然后我创建了两个独立的控制器,如下所示:

    .controller('DashboardController', ['ControllerService', 'CenterService', 'companyId', 'centers', function (Controller, service, companyId, centers) {
    
        // Assign this to a variable
        var self = new Controller(service);
    
        self.list = centers;
    }])
    
    .controller('CompanyController', ['ControllerService', 'CompanyService', 'ArrayService', 'companies', function (Controller, service, arrayService, centers) {
    
        // Assign this to a variable
        var self = new Controller(service);
    
        self.list = companies;
    }])
    

    希望您可以看到我注入 ListControllerService 的服务对于每个控制器都是不同的。我的例子中唯一的警告是每个"服务"必须有一个删除方法(不是那么困难,因为它们都是api服务)。

    我希望能更好地解释事情。

1 个答案:

答案 0 :(得分:0)

我在当前项目中使用的解决方案是编写一个注册工厂的函数。

function CreateMyGenericFactory(factoryName, serviceName)
    app.factory(factoryName, [serviceName, function (service){

        var GenericListFactory = {
            list: [],
            pageSizes: [10, 20, 50, 100],
            predicate: 'name',
            reverse: false,
            filter: ''
            delete: function(e, model){
                service.delete(model.id);
            }
        }

        GenericListFactory.pageSize = GenericListFactory.pageSizes[0];

        return GenericListFactory;

    }]);
}

然后在JS中执行该函数以动态注册新工厂。

CreateMyGenericFactory('ListFactory', 'ListService');

并在你的控制器中使用它。

app.controller('GenericListController', ['ListFactory', function (ListFactory) {
  ...
  console.log(ListFactory.pageSizes.length); // -> 4
  ListFactory.delete(e, model);
}];

我还在CreateMyGenericFactory函数中注册了服务以进一步减少重复,如果每个工厂都有自己的服务,您也可以考虑这样做。

最终解决方案看起来像这样。

function CreateMyGenericFactory(name)
    var factoryName = name + 'Factory'; // e.g. listFactory
    var serviceName = name + 'Service'; // e.g. listService

    app.factory(factoryName, [serviceName, function (service){

        var factory = {
            list: [],
            pageSizes: [10, 20, 50, 100],
            predicate: 'name',
            reverse: false,
            filter: ''
            delete: function(e, model){
                service.delete(model.id);
            }
        }

        factory.pageSize = factory.pageSizes[0];

        return factory;

    }]);

    app.service(serviceName, ['$resource', function (resource){

        return $resource(Modus[backend] + '/api/'+slug+'s/:id', {
            id: '@_id'
        });

    }]);
}

这样我可以注册我需要的所有工厂和服务,而无需复制任何代码。

CreateMyGenericFactory('user');
// this registered userFactory and userService