gpt4 book ai didi

javascript - 改进 AngularJS 指令代码

转载 作者:行者123 更新时间:2023-11-29 10:10:37 27 4
gpt4 key购买 nike

我写了一个 AngularJS 指令,但我对此很陌生,我不知道我是否以“Angular 方式”完成了...

这是我的代码: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('[wait-button="'+id+'"]') 部分有点“讨厌”……(或者不是?);否则我不知道在同一个 Controller 中不同时间重复使用同一个指令的更好方法。有人可以建议我更好的代码吗?

谢谢。

最佳答案

访问指令中的元素

我提倡对这种类型的事情使用 link 函数:

link: function($scope, elem, attrs){ /* do something w. elem */ }

在 Controller 中访问您的元素不是很有 Angular 。这就是指令对象的 linkcompile 函数的全部意义....

...但在极少数情况下这是合理的。 Controller 中注入(inject)的 $element 引用了你的 angular.element(document.querySelector('[wait-button="'+id+'"]'))代码正在做。此时你只需要使用$element。但我可以完全推荐一种更 Angular 方法吗?

相互交流。 Controller 和指令

另一个问题是您如何基本上将您的意图从指令传达给主 Controller 并返回给指令。您的用例与大多数用例略有不同,因为您具有异步性质。

我做了一个利用隔离作用域和回调参数的示例。在大多数真实场景中,您将处理异步回调的 promise 。因此,我使用 promise 中的 .finally 逻辑来执行回调,该回调与异步逻辑已结束的指令进行通信。

在我的例子中要记住的事情:

  • 我使用 coffeescript 是因为我用这种方式编写代码很理智
  • 我使用 CSS/DOM 来驱动如何指令的 loading 状态应该出现,而不是尝试以编程方式进行。在我的书中,程序化 DOM 操作非常反 NG。指令为您提供了足够的能力以声明方式执行此类操作。
  • 我没有使用指令 Controller ,因为除非您要为指令使用模板,否则您真的不需要自定义 Controller 。当您使用 link 函数与自定义指令 Controller 时,有一条模糊的界线。
  • 哦...我使用了 *controller as• 语法,因为如果您阅读任何有关 NG 的发展方向的信息,它们将远离整个 $scope 范式。

plunker - http://plnkr.co/edit/0AvlCQW5qqkpYKl2WpB3?p=preview

声明式用户界面

主 Controller

.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

实现用户界面

<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})

关于javascript - 改进 AngularJS 指令代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34229868/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com