【发布时间】:2015-11-25 14:13:25
【问题描述】:
为了描述这个问题,我创建了一个完整的示例。我的实际应用程序比演示的还要大,每个控制器操作的服务和指令更多。这会导致更多的代码重复。我试着放一些代码 cmets 来澄清一下, PLUNKER:http://plnkr.co/edit/781Phn?p=preview
重复部分:
routerApp.controller('page1Ctrl', function(pageFactory) {
var vm = this;
// page dependent
vm.name = 'theOne';
vm.service = 'oneService';
vm.seriesLabels = ['One1', 'Two1', 'Three1'];
// these variables are declared in all pages
// directive variables,
vm.date = {
date: new Date(),
dateOptions: {
formatYear: 'yy',
startingDay: 1
},
format: 'dd-MMMM-yyyy',
opened: false
};
vm.open = function($event) {
vm.date.opened = true;
};
// dataservice
vm.data = []; // the structure can be different but still similar enough
vm.update = function() {
vm.data = pageFactory.get(vm.service);
}
//default call
vm.update();
})
基本上我将所有我能做的逻辑都移到了工厂和指令中。但是现在在每个使用特定指令的控制器中,我需要一个字段来保存指令正在修改的值。它的设置。后来我需要类似的字段来保存来自dataservice的数据,调用本身(方法)也是一样的。
这会导致大量重复。
从图形上看,当前示例如下所示:
虽然我认为正确的设计应该看起来更像这样:
我试图在这里找到一些解决方案,但似乎都没有得到证实。我发现了什么:
- AngularJS DRY controller structure,建议我通过 $scope 或 vm 并用额外的方法和字段装饰它。但许多消息来源说这是肮脏的解决方案。
-
What's the recommended way to extend AngularJS controllers? 使用 angular.extend,但是在使用
controller as语法时会出现问题。 - 然后我也找到了答案(在上面的链接中):
您不扩展控制器。如果它们执行相同的基本功能,则需要将这些功能转移到服务中。该服务可以注入到您的控制器中。
即使我这样做了,仍然有很多重复。或者它只是必须的方式?像 John Papa sais (http://www.johnpapa.net/angular-app-structuring-guidelines/):
尽量保持 DRY(不要重复自己)或 T-DRY
您是否遇到过类似的问题?有哪些选择?
【问题讨论】:
-
听起来这是一个“他们在多大程度上不同”的问题。这是一个非常主观的问题——如果没有具体的细节,我认为站在一边是不对的。但是,当您最了解您的应用程序时,将其移至服务中感觉不对,那么它可能就是不正确的做法。但是,如果您提供一些代码,也许其他成员可以对此有所了解。
-
我给出了更多真实数据的例子,但我认为它不会有帮助。它是 - 如前所述,只是某些指令或服务使用的大多数变量。但问题是我仍然需要为每个使用类似控制器的视图重新定义它们。
-
John Papa 还写道 _“保持干燥很重要,但如果它在 LIFT 中牺牲其他人则并不重要”。考虑将控制器拆分为更小的控制器和/甚至指令。组件越小,可重复使用的机会就越高。
-
@zeroflagL 但现在这就是问题所在。我确实尽可能地拆分它,但现在我有例如 6-10 个视图使用相同的指令,这需要声明相同的字段。例如需要日期字段和日期格式的日期选择器。它不能在不破坏 LIFT 的情况下组合成更大的指令,但现在每个视图都必须一遍又一遍地声明相同的字段。以完全相同的方式。就我而言,它实际上是反复复制的 2-3 个指令的组合。那么有什么方法可以让这个更干吗?
-
我通过使用允许父子状态的 ui-router 解决了这个问题。我将有一个父控制器,每个子控制器都会调用它。
标签: javascript angularjs design-patterns dry angularjs-controller