我最近继承了第三方开发人员编写的角度模块。我之前从未使用角度,并且被要求做出一些相当基本的改变,但是我正在努力解决几个问题(我保证在这个问题的末尾有一个问题)。
本质上,模块只是一个多选问卷,带有一系列按钮,您可以单击一个选择答案,然后单击前进/后退按钮以在问题之间移动。
当模块硬编码为使用5个按钮时,按钮的位置在控制器中设置如下:
// scope here is the scope for the main controller
$scope.answerOptions = [
{ pos: 70 },
{ pos: 215 },
{ pos: 360 },
{ pos: 505 },
{ pos: 650 }
];
pos只是左偏移,垂直位置是固定的。这是在模板上实现的,如下所示:
<div class="circle" ng-repeat="o in answerOptions"
option-pos="{{o.pos}}"
ng-hide="sectionEnd"
ng-class="selectedOptionStyle($parent.selectedAnswer - 1 == $index)"
ng-click="selectAnswer($index)">
</div>
然后指令optionPos
:
.directive('optionPos', function(){
return function(scope, elm, attrs) {
attrs.$observe('optionPos', function(x){
elm.css('left', x - 60 + 'px');
})
}
})
我被要求使用任意数量的按钮并在x和y中定位,并允许自定义的答案(此时它只是将点击按钮的数组索引发送回服务器)。我认为这将是一个简单的改变,并且不可否认,如果我实现相同的系统,使用插值设置x和y,然后只需将y添加到optionPos指令就足够了。但是我对这种方法有几个问题:
attrs.$observe
是不必要的资源密集型,因为一旦模块加载,值将永远不会改变,$ observe(可能是?)将监视添加到该属性。类似地,使用插值来设置DOM元素上的坐标。在大量阅读Angular的文档和教程后,我尝试做的是这样的:
// this would no longer be hard coded into the controller
// but once it is retrieved, this is what is set in the scope
// scope is still the main controller scope
$scope.answerOptions = [
{ Answer: 1, pos: { X: 180, Y: 120} },
{ Answer: 2, pos: { X: 360, Y: 120} },
{ Answer: 3, pos: { X: 540, Y: 120} }
];
模板:
<div class="circle" ng-repeat="o in answerOptions"
answer-option="o"
option-button
ng-hide="sectionEnd"
ng-class="selectedOptionStyle($parent.selectedAnswer - 1 == $index)"
ng-click="selectAnswer(o.Answer)">
</div>
指令:
.directive('optionButton', function(){
return {
restrict: 'A',
scope: {
answerOption: '='
},
link: function(scope, elm, attrs) {
elm.css('left', scope.answerOption.pos.X - 60 + 'px');
elm.css('top', scope.answerOption.pos.Y - 60 + 'px');
}
}
上面的解决方案的问题是我的指令是创建一个独立的范围,所以所有其他带有函数调用的指令,例如ng-hide
现在都被打破了,我不想要重新构建整个模块,实质上是一个非常简单的变化
所以,正如我漫长的漫无目的所承诺的那样 - 问题:
对于任何超过24小时角度经验的人,我是否会采取这种错误方式?我遇到的问题让我觉得这就像代码味道一样,但我不确定它是否因为原始开发人员以难以维护/扩展的方式编写模块,或者我正在服用完全错误的做法。我遇到的问题似乎源于这样一个事实,即基本上整个应用程序逻辑被设置为主控制器范围内的各种功能。它需要大约800行JS来设置该控制器的范围,许多函数定义了大量不同的东西。这是应该构建角度应用程序的方式,范围内的大多数逻辑,然后直接从模板调用它,例如, ng-hide="sectionEnd"
?
答案 0 :(得分:1)
一个怪物控制器不是好习惯。页面上的每个控制器都应该是聚焦的,并且最多应该有5个方法(指南)。通过集中控制器,您可以管理应用程序获取数据的方式。
一旦你有控制器来检索你的应用程序数据,你应该利用指令将功能封装到可重用的指令中。
此外,如果属性及其插值永远不会改变,$ observe将不会产生大量成本。
我建议遵循以下准则: