用于CRUD UI的AngularJS,DRY控制器

时间:2014-01-21 16:09:24

标签: angularjs controller crud dry

我有一堆数据类型:用户,产品,类别。我有一个视图/控制器用于CRUDing每种类型的数据。因此,我的视图允许创建项目,它显示一个列表,并且您可以编辑和更新每个项目,或删除它。
控制器管理所有UI交互。例如,当删除项目时,用户可以访问取消按钮几秒钟。进入控制器,所有CRUD操作都通过服务完成。

angular.module('myApp').controller(
'UsersManagerController', 
function UsersManagerController($scope, $timeout, userService) {

$scope.deleteUser = function(user) {    
    user.deleting = true;
    user.deletionCancelable = true;
    user.deletePromise = $timeout( function() {
        user.deletionCancelable = false;
        userService.deleteUser(user.id);
    }, 2000);       
};

$scope.isUserDeleting = function(user) {
    return user.deleting;
}

$scope.cancelDelete = function(user) {
    $timeout.cancel(user.deletePromise);
    user.deletePromise = null;
    user.deleting = false;
    user.deletionCancelable = false;
}   

现在,我想避免为每种类型的数据(产品,类别......)重复此控制器代码,并且只写几个视图。这意味着我想要一个可以动态接收服务的单个控制器,从而为特定数据类型公开CRUD方法。我设法使用$ injector执行此操作。 但我不知道如何从视图中为控制器提供服务名称。我试过这个:

<div ng-controller="ItemsManagerController" ng-init="setItemService('userService')">

进入控制器:

    var _crudService;
    $scope.setCrudService = function(serviceName) {
        _crudService = $injector.get(serviceName);
}

但是setCrudService()在运行时被调用,由AngularJs绑定管理。这意味着我无法准确知道它何时被调用,之前调用我的控制器的其他一些方法,尝试使用尚未设置的服务。

有谁知道怎么做?
也许我的设计有缺陷?


更新:
我找到了一个解决方案:范围继承。

<div ng-controller="UsersManagerController">
<div ng-controller="ItemsManagerController">
    <div ng-repeat="user in items">
        <span ng-click="deleteItem(user.id)">Remove {{user.name}}</span>
    </div>
</div>
</div>

1)首先初始化UsersManagerController 2)ItemsManagerController范围将继承UsersManagerController范围。

angular.module('myApp').controller('UsersManagerController', 
['$scope', 'userService', function UsersManagerController($scope, userService) {    
    $scope.crudService = userService;
}]);    

angular.module('myApp').controller('ItemsManagerController', 
['$scope', function ItemsManagerController($scope) {    

    $scope.deleteItem = function(itemId) {
        $scope.crudService.delete(itemId);
    }

    $scope.items = crudService.getItems();
}]);    

它可以工作,但我必须为每种数据类型编写一个控制器。我仍在寻找更优雅的解决方案。

1 个答案:

答案 0 :(得分:0)

我能想到这样的方式

设置CRUD生成服务

app.service('CRUDService', function($timeout) {
  return {

      setCRUD: function(scope, service, objName) {

          var funcName = "delete" + objName;
          scope[funcName] = function(obj) {    
              obj.deleting = true;
              obj.deletionCancelable = true;
              obj.deletePromise = $timeout( function() {
                  obj.deletionCancelable = false;
                  service.deleteUser(user.id);
              }, 2000);       
          };

          funcName = "is" + objName + "Deleting";
          scope[funcName] = function(obj) {
              return obj.deleting;
          }

          scope.cancelDelete = function(obj) {
              $timeout.cancel(obj.deletePromise);
              obj.deletePromise = null;
              obj.deleting = false;
              obj.deletionCancelable = false;
          }    

      }

}

然后,在控制器中,使用它

   CRUDService.setCRUD($scope, userService, "User");