提高AngularJS指令code [英] Improve AngularJS directive code
问题描述
我写了一个AngularJS指令,但我pretty新的吧,我不知道如果我在角办法做了...
I wrote an AngularJS directive, but I'm pretty new about it, and I don't know if I done in the "Angular way"...
下面是我plunker与code:的http:// plnkr。 CO /编辑/ X1tOk4z8f6dCK3mfB7HP?p = preVIEW
Here is my plunker with the code: http://plnkr.co/edit/X1tOk4z8f6dCK3mfB7HP?p=preview
HTML
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<meta charset=utf-8 />
<title>Directive Test</title>
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<button id="button1" ng-click="dummyClickFoo()" wait-button="foo"><i></i> Foo</button>
<button id="button2" ng-click="dummyClickBar()" wait-button="bar"><i></i> Bar</button>
</body>
</html>
JS:
app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.dummyClickFoo = function() {
$scope.startSpinner('foo');
setTimeout(function() {
$scope.stopSpinner('foo');
}, 3000);
};
$scope.dummyClickBar = function() {
$scope.startSpinner('bar');
setTimeout(function() {
$scope.stopSpinner('bar');
}, 3000);
};
});
app.directive('waitButton', function() {
return {
restrict: 'A',
controller: ['$scope', '$element', function($scope, $element) {
$scope.startSpinner = function(id) {
var el = angular.element(document.querySelector('[wait-button="'+id+'"]'));
el.children('i').text('searching...');
};
$scope.stopSpinner = function(id) {
var el = angular.element(document.querySelector('[wait-button="'+id+'"]'));
el.children('i').empty();
};
}]
};
});
我发现 document.querySelector('[等待按钮=+身份证+']')
的一部分,这是一个有点讨厌...... (或不?);否则我不知道有更好的方式在同一个控制器来重新使用相同的指令不同的时间。
有人建议我一个更好的code?
I find that the document.querySelector('[wait-button="'+id+'"]')
part, it's a bit "nasty"... (or not?); otherwise I don't know a better way to re-use the same directive different times in the same controller.
Can someone suggest me a better code?
感谢您。
推荐答案
我提倡使用链接
功能这种类型的事情:
accessing the element in the directive
I'd advocate using the link
function for this type of thing:
link: function($scope, elem, attrs){ /* do something w. elem */ }
这不是很的角杂交的被访问控制器的元素。这就是链接
&放的整点; 编译
指令对象等功能。
It's not very angular-ish to be accessing your element in the controller. That's the whole point of the link
& compile
functions of the directive object....
...但在罕见的情况下,这是有道理的。注入的 $元素
在你的控制器引用了同样的事情你的 angular.element(document.querySelector('[等待按钮=+身份证+' ]'))
code在做什么。你只需要使用 $元素
在这一点上。但我可以推荐一个更加棱角分明的做法完全?
... but in rare cases this is justified. The injected $element
in your controller references the same thing your angular.element(document.querySelector('[wait-button="'+id+'"]'))
code is doing. You only need to use $element
at this point. But may I recommend a more angular approach altogether?
另一个问题是如何你基本上是从指令传达你的意图给主控制器和回指令。您的使用情况比大多数在你有一个异步的性质有所不同。
The other issue is how you're basically communicating your intent from the directive to the main controller and back to the directive. Your use case is a little different than most in that you have an async nature.
我已经做了充分利用的分离范围和回调参数的例子。在大多数现实世界的情景,你会要处理的承诺为异步回调。因此,我使用了。最后
逻辑和承诺来执行通信回指令,无论异步逻辑已结束回调。
I have made an example that leverages an isolate scope and callback parameters. In most real-world scenarios you'll be dealing with promises for async callbacks. As such, I used the .finally
logic from the promises to execute the callback that communicates back to the directive that whatever async logic has wrapped up.
事情要牢记在我的例子:
Things to keep in mind in my examples:
- 我用的CoffeeScript,因为我code三立这样
- 我用CSS / DOM来驱动如何的加载的指令的状态应该会出现,而不是试图以编程方式做到这一点。编程DOM操作非常多的反NG在我的书。指令为你提供足够的做这样的事情声明。
- 我没有使用该指令控制器,因为除非你打算使用模板为您的指令,你真的不需要定制控制器。还有当你去一个
链接
函数与自定义指令控制器的模糊线。 - 呵呵......我用*控制器•语法,因为如果你读到哪里NG是怎么回事,他们是从整个
$范围
模式搬走东西
- I used coffeescript because I code sanely that way
- I used CSS/DOM to drive how the loading state of the directive should appear rather than trying to do it programmatically. Programmatic DOM manipulation is very much anti-NG in my book. Directives provide you with enough to do things like this declaratively.
- I didn't use the directive controller because unless you're going to use a template for your directive, you really don't need a custom controller. There is a fuzzy line of when you go with a
link
function versus a custom directive controller. - Oh... and I used the *controller as• syntax because if you read anything about where NG is going, they are moving away from the whole
$scope
paradigm.
的 plunker - http://plnkr.co/edit/0AvlCQW5qqkpYKl2WpB3? p = preVIEW 的
主控制器
.controller 'MainCtrl', class MainCtrl
@$inject = [
'$scope'
'$interval'
]
constructor: ($scope, @$interval)->
@viewData = 'Skynet 2.0'
@isLoading = false
callbackExample: ($callbackFunc)->
@loadRqst()
.finally -> $callbackFunc?()
loadRqst: ->
@isLoading = 1
# this returns a promise which gets processed in the example functions
@$interval =>
console.log @isLoading++
, 250, 10
.finally =>
@isLoading = false
实施UI
<button callback-btn="vc.callbackExample($callbackFunc)">
Callback Example<i> - I'm loading & I'm #1</i>
</button>
<button callback-btn="vc.callbackExample($callbackFunc)">
Callback Example<i> - Look I can load too, I'm #2</i>
</button>
CSS
[callback-btn] i{
display: none;
}
[callback-btn].loading i{
display: initial;
}
指令
.directive 'callbackBtn', ($parse)->
dir =
restrict: 'A'
scope: { callbackBtn: '&' }
link: ($scope, elem, attrs)->
onCallback = ->
console.log 'on callback'
elem.removeClass 'loading'
elem.on 'click', ->
elem.addClass 'loading'
$scope.$apply ->
$scope.callbackBtn({$callbackFunc: onCallback})
这篇关于提高AngularJS指令code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!