我想知道如何根据Rober C.Martin的《干净代码》一书将功能封装在角度指令中。我想省略注释,改为使用带有发音名称的函数。
想象一下这个代码:
app.directive('myDirective' function() {
return {
link: function(scope) {
// initialize visual user state
scope.visualUserState = {
// some very detailed state initialization
}
}
})
为了封装加载功能,我想替换如下代码:
app.directive('myDirective' function() {
return {
link: function(scope) {
scope.initializeVisualUserState = function() {
scope.visualUserState = {
// some very detailed state initialization
}
}
scope.initializeVisualUserState();
}
})
我不喜欢第二种方法的地方是,"loadDataFromServer"是一些只由链接函数使用而不由视图使用的功能,因此我违反了作用域应该只包含用于与视图交互的数据和函数的规则。
此外,我认为代码的可读性不太好。
由于该功能处理指令中非常私人的内容,我认为使用和注入服务不是正确的做法。
封装此功能的更好做法是什么?
您应该使用控制器为指令添加逻辑。在您的控制器中,您可以注入服务。最好只为一个目的编写一个服务,只需让您的控制器调用这些服务。
事实上,只有在需要DOM节点的情况下才应该使用link函数,这实际上非常接近于never。
阅读John Papa 的风格指南
angular.module('myModule', []);
// Controller
(function() {
angular
.controller('myModule')
.controller('MyController', ['$scope', 'DataService', function($scope, DataService) {
DataService
.retrieveData()
.then(function(data) {
$scope.visualUserState = data;
});
}]);
})();
// Directive
(function() {
angular
.module('myModule')
.directive('myDirective', function() {
return {
'restrict': 'E',
'scope': true,
'controller': 'MyController',
'controllerAs': '$ctrl'
};
});
})();
(function(module){
module.directive('myDirective', myDirective);
function myDirective(){
var directive = {
link : link,
scope : {state : '='},
restrict : 'EA',
template : //Some template which uses state
}
return directive;
function link(){
}
};
module.controller('myController', myController);
myController.$inject = ['$scope', 'OtherService'];
function myController(scope, service){
//service is used to pull the data and set to $scope.userState.
}
})(angular.module('myApp'))
你的指令是:
<myDirective state="userState"></myDirective>
如果这有帮助,请告诉我。