【问题标题】:AngularJS, DRY controllers for CRUD UIAngularJS,CRUD UI 的 DRY 控制器
【发布时间】:2014-02-11 08:28:45
【问题描述】:

我有一堆数据类型:用户、产品、类别。我有一个视图/控制器用于对每种类型的数据进行 CRUD。因此,我的视图允许创建一个项目,它显示一个列表,并且您可以对每个项目进行编辑和更新,或删除它。
控制器管理所有 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();
}]);    

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

【问题讨论】:

  • 我之前这样做的方法是创建一个指令来管理实体的 CRUD 操作,该实体设置在指令的 init 函数中。为什么没有指令并将“EntityType”作为属性并做类似的事情?可以根据实体决定返回服务器的帖子。如果您觉得这听起来不错,我可以详细说明吗?
  • 感谢您的回答,是的,我想了解更多信息 :-) 控制器将如何与指令交互?如果单击删除按钮,则会调用控制器 $scope.deleteItem()。它如何知道如何删除可以是用户、产品或类别的项目?此外,如果数据类型是用户或产品,则视图也不相同。我最初的想法是将控制器视为 API 提供者,视图使用此 API。
  • 您可以将事件传递到指令中,并根据需要连接回调。我会对每个实体都有一个指令,例如 。关于数据的加载和保存方式,我使用restangular,每个实体都有自己的控制器,所以我可以做 Restangular.all(entityName).getList()... 所以指令本身管理删除/更新/创建的实体。不同实体的数据看起来不同,所以我使用了一个元数据控制器,它返回一个实体的字段,并且 crud 网格在此基础上构建自己。
  • 另一种方法是直接在 UsersManagerController 中实例化 ItemsManagerController。见stackoverflow.com/questions/18461263/…

标签: angularjs controller crud dry


【解决方案1】:

我可以这样想

设置 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");

【讨论】:

  • 我喜欢您在 setCRUD 对象中创建动态函数的方式 :-) 但是...它不符合我的需求:如何为控制器提供 userService 或 productService?使用您的代码,我必须为每种数据类型编写一个控制器,并且 UI 交互代码将在每个数据类型中重复。现在我有一个控制器,它能够通过服务管理所有类型的视图(视图必须尊重控制器 API)和所有类型的数据类型。如何使用给定数据类型的所需服务初始化控制器?
猜你喜欢
  • 1970-01-01
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 2016-01-16
相关资源
最近更新 更多