【发布时间】: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