我读了这两篇很棒的文章:
Jonathan Creamer的 angularjs 控制器状态
和
Todd Motto重新思考 AngularJS 控制器
在这些文章中,作者讨论了使用控制器(使它们成为视图和模型之间的桥梁)和工厂/服务(业务逻辑应该真正存在的地方)的正确方法。
这是很好的信息,我很高兴开始在我的一个项目中重构控制器,但我很快发现,如果你有一个丰富的对象模型,文章中显示的结构就会崩溃。
以下是“重新思考 Angularjs 控制器”中设置的回顾:
这是控制器:
app.controller('InboxCtrl', function InboxCtrl (InboxFactory) {
var vm = this;
vm.messages = InboxFactory.messages;
vm.openMessage = function (message) {
InboxFactory.openMessage(message);
};
vm.deleteMessage = function (message) {
InboxFactory.deleteMessage(message);
};
InboxFactory
.getMessages()
.then(function () {
vm.messages = InboxFactory.messages;
});
});
这是工厂:
app.factory('InboxFactory', function InboxFactory ($location, NotificationFactory) {
factory.messages = [];
factory.openMessage = function (message) {
$location.search('id', message.id).path('/message');
};
factory.deleteMessage = function (message) {
$http.post('/message/delete', message)
.success(function (data) {
factory.messages.splice(index, 1);
NotificationFactory.showSuccess();
})
.error(function () {
NotificationFactory.showError();
});
};
factory.getMessages = function () {
return $http.get('/messages')
.success(function (data) {
factory.messages = data;
})
.error(function () {
NotificationFactory.showError();
});
};
return factory;
});
这很好,因为providers
(工厂)是单例的,数据在视图之间维护,并且可以访问而无需从 API 重新加载。
如果messages
是顶级对象,这很好用。但如果他们不是,会发生什么?如果这是一个用于浏览其他用户收件箱的应用程序怎么办?也许您是管理员,并且您希望能够管理和浏览任何用户的收件箱。也许您需要同时加载多个用户的收件箱。这是如何运作的?问题是收件箱消息存储在服务中,即InboxFactory.messages
.
如果层次结构是这样的:
Organization
|
__________________|____________________
| | |
Accounting Human Resources IT
| | |
________|_______ _____|______ ______|________
| | | | | | | | |
John Mike Sue Tom Joe Brad May Judy Jill
| | | | | | | | |
Inbox Inbox Inbox Inbox Inbox Inbox Inbox Inbox Inbox
现在messages
在层次结构中有几个层次,它们本身没有任何意义。您不能在工厂中存储消息,InboxFactory.messages
因为您必须一次检索多个用户的消息。
现在您将拥有一个 OrganizationFactory、一个 DepartmentFactory、一个 UserFactory 和一个 InboxFactory。检索“消息”必须在 a 的上下文中user
,who 在 a 的上下文中,在 adepartment
的上下文中organization
。数据应该如何以及在哪里存储?应该如何取回?
那么这应该如何解决呢?控制器、工厂/服务和富对象模型应该如何构建?
在我思考的这一点上,我倾向于保持精简而不是拥有丰富的对象模型。只需将对象存储在注入控制器的 $scope 上,如果您导航到新视图,请从 API 重新加载。如果您需要一些跨视图持久化的数据,您可以使用服务或工厂构建桥梁,但这不应该是您做大多数事情的方式。
其他人是如何解决这个问题的?这有什么模式吗?