Angular: 如何在指令中封装逻辑?
Angular: How to encapsulate logic in a directive?
我想知道如何根据 Rober C. Martin 的 "Clean Code" 书将功能封装在 angular 指令中。我想省略注释,改用会说名字的函数。
想象一下这段代码:
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" 是一些只被 link 函数使用而不被视图使用的功能,所以我违反了范围应该仅保存用于与视图交互的数据和函数。
而且我认为代码的可读性不是很好。
由于该功能处理指令中非常私密的内容,我认为使用和注入服务不是正确的方法。
封装此功能的更好做法是什么?
您应该使用控制器向您的指令添加逻辑。在您的控制器中,您可以注入服务。最好写一个单一用途的服务,让你的控制器调用服务。
事实上,如果您需要 DOM-节点,您应该只使用 link 函数,这实际上非常接近于从不。
阅读 John Papa 的 styleguide
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>
如果有帮助请告诉我。
我想知道如何根据 Rober C. Martin 的 "Clean Code" 书将功能封装在 angular 指令中。我想省略注释,改用会说名字的函数。
想象一下这段代码:
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" 是一些只被 link 函数使用而不被视图使用的功能,所以我违反了范围应该仅保存用于与视图交互的数据和函数。
而且我认为代码的可读性不是很好。
由于该功能处理指令中非常私密的内容,我认为使用和注入服务不是正确的方法。
封装此功能的更好做法是什么?
您应该使用控制器向您的指令添加逻辑。在您的控制器中,您可以注入服务。最好写一个单一用途的服务,让你的控制器调用服务。
事实上,如果您需要 DOM-节点,您应该只使用 link 函数,这实际上非常接近于从不。
阅读 John Papa 的 styleguide
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>
如果有帮助请告诉我。