我有两种形式在视觉上90%相同,并且表单的支持代码是90%相同。因此,我在两者之间有 90%重复代码,我想消除它。
在我的设置中,我有一个模型,其他两个模型扩展。表单(视图)只是这些模型的投影,它们的输入元素映射到每个模型的字段。
画报:
____________________________
| Base Model |
------------------------------
| |
| |
_____________ _____________
| Sub Model A | | Sub Model B |
--------------- ---------------
| |
|*projected with*|
_____________ _____________
| Form A | | Form B |
--------------- ---------------
正如我之前提到的,模型A和B大约相同(这就是为什么它们从基础模型开始继承)。这些模型实现了方法save()
,load()
和destroy()
,它们会自动与我的后端通信,以正确更新所表示对象的持久状态。
模型A和B每个都有一个控制器,它实现了修改模型数据的方法。模型A有一个控制器,模型B有一个控制器 - 这些控制器与模型非常相似,90%相同。这些控制器驱动表单的核心功能(诸如设置下拉列表,获取其他数据,初始化点击处理程序等等)。它们每个都实现save()
,只需在相应的模型上调用save()
方法。
重申一下,我的问题是 90%的代码是重复的,因为这两个模型的90%是相同的
简短示例:
说我有一个输入元素组有两个输入:First Name
和Last Name
。还假设我想检查我的数据库以确保Last Name
值已存在。
模型A的save()
方法将:
Last Name
值,如果不存在则创建<First Name> <Last Name>
模型B的save()
方法将:
Last Name
值,如果不存在则创建<Last Name>, <First Name>
现在我在Last Name
的查找或创建中有重复的代码。随着更大和更复杂的表单字段,此代码重复变得失控。这甚至不考虑控制器,它们也有重复的代码,可以为Last Name
输入设置自动完成预先输入框。
还有多种类型的重叠:
我最初的尝试,最终失败了,就是为表单的每个组件创建一个视图和控制器。我有两个主要视图(每个模型一个)使用ng-include
来包含每个表单组件。 ng-include
将指定实现save()
和load()
的控制器,父控制器将调用该控制器。
示例:
<ng-include
src="'app/forms/name.htm'" <--- view HTML for the name component
ng-controller="FormNameController" <--- controller for the name component
></ng-include>
我的想法是让每个组件控制器实现:
save()
方法load()
方法然后我会使用整个页面的控制器来调用所有组件控制器的save()
和load()
方法。
这种方法有两个主要问题(在许多小问题中):
broadcast
,emit
和on
似乎有一些奇怪的方法,但它似乎非常hacky(因为我还需要save()
,load()
方法在组件控制器上返回promises 由于我正在使用框架(AngularJS),我认为有某种类型的&#34; Angular&#34;有效地做到这一点的方法。我花了很长时间环顾四周寻找一个很好的方法,但找不到任何东西。
任何帮助,输入或推动正确的方向都将非常感激。我不确定是在这里发布还是在programmers.stackexchange.com上发布;希望这是正确的地方。
答案 0 :(得分:0)
Angular的方法是使用服务。 您可以将大部分控制器逻辑分解为服务,以保持控制器清洁并保持代码可重用。
例如,并且不会过多地假设您的实现。
app.factory('baseService', [function(){
var base = {};
base.save = function(data){
//persist data
};
base.findOrCreate = function(value){
//...
}
return base;
}]);
app.factory('aService', ['baseService', function(baseService){
var a = {};
a.save = function(aModel){
baseService.findOrCreate(aModel.lastName);
//do something
baseService.save(aModel);
};
return a;
}]);
app.controller('aController', ['$scope', 'aService', function($scope, aService){
//...
$scope.save() = function(){
//...
aService.save($scope.aModel);
};
}]);