Angular 指令和 Jquery slideToggle 函数的实现
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15444244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular directive and Jquery slideToggle function implementation
提问by Osy
Using angular and jquery I implemented slideToggle function. In order to only apply this function to one specific HTML element, I am using within ng-click function one parameter, my code works fine but, I want to know if exists another better way to implement directives and ng-click functions in angular:
使用 angular 和 jquery 我实现了 slideToggle 功能。为了仅将此函数应用于一个特定的 HTML 元素,我在 ng-click 函数中使用了一个参数,我的代码运行良好,但是,我想知道是否存在另一种更好的方法来实现指令和 ng-click 函数的角度:
index.html
索引.html
<!DOCTYPE html>
<html ng-app="myApp" ng-controller="MainController">
<head>
<title></title>
<link type="text/css" rel="stylesheet" href="css/styles.css"/>
</head>
<body>
<div>
<input type="button" ng-click="toggle('first')" value="Toggle First">
<input type="button" ng-click="toggle('second')" value="Toggle Second">
<input type="button" ng-click="toggle('third')" value="Toggle third">
<div class="div1" section="first" toggle="first" >
<p>This is section #1</p>
</div>
<div class="div1" toggle="second">
<p>This is another section #1</p>
</div>
<div class="div1" toggle="third">
<p>This is 3 section #1</p>
</div>
</div>
</body>
<footer>
<script src="js/jquery.min.js"></script>
<script src="js/angular.js"></script>
<script src="js/directives.js"></script>
</footer>
</html>
styles.css
样式文件
.div1 {
background: Brown;
width: 200px;
height: 200px;
text-align: center;
}
.div1 p {
position: relative;
top: 50%;
}
directives.js
指令.js
angular.module("myApp", []) //
.controller('MainController', function($scope) {
$scope.toggle = function(section) {
console.log('<toggle function> section :' + section);
$scope.section = section;
$scope.$broadcast('event:toggle');
}
}) //
.directive('toggle', function() {
return function(scope, elem, attrs) {
scope.$on('event:toggle', function() {
if(attrs.toggle == scope.section){
elem.slideToggle('fast');
}
});
};
});
One concern of my own is the way that I am communicating between directive and scope:
我自己关心的一个问题是我在指令和范围之间进行通信的方式:
$scope.section = section;
and
和
if(attrs.toggle == scope.section){
I will appreciate any advice for a better Angular implementation.
对于更好的 Angular 实现,我将不胜感激。
Thanks
谢谢
回答by GFoley83
Plunker Demo:http://plnkr.co/edit/u69puq?p=preview
Plunker 演示:http ://plnkr.co/edit/u69puq?p=preview
FYI, at the time of writing, the AngularJS team are adding an ngAnimatedirective which will (hopefully) offer most of the animate functionality that jQuery currently offers, e.g. Slide, Fade etc, which is sorely missing at the moment IMO.
仅供参考,在撰写本文时,AngularJS 团队正在添加一个ngAnimate指令,该指令将(希望)提供 jQuery 当前提供的大部分动画功能,例如 Slide、Fade 等,目前 IMO 非常缺少这些功能。
HTML
HTML
<div data-ng-controller="MainController">
<input type="button" value="Toggle First" ng-click="box1=!box1">
<input type="button" value="Toggle Second" ng-click="box2=!box2">
<input type="button" value="Toggle third" ng-click="box3=!box3">
<div class="div1" data-slide-toggle="box1" data-slide-toggle-duration="100" >
<p>This is section #1</p>
</div>
<div class="div2" data-slide-toggle="box2" data-slide-toggle-duration="2000">
<p>This is another section #1</p>
</div>
<div class="div3" data-slide-toggle="box3">
<p>This is 3 section #1</p>
</div>
</div>
JS
JS
var myApp = angular.module("myApp", []);
myApp.controller('MainController', function($scope) {
$scope.box1 = $scope.box2 = $scope.box3 = true;
});
myApp.directive('slideToggle', function() {
return {
restrict: 'A',
scope:{
isOpen: "=slideToggle"
},
link: function(scope, element, attr) {
var slideDuration = parseInt(attr.slideToggleDuration, 10) || 200;
scope.$watch('isOpen', function(newVal,oldVal){
if(newVal !== oldVal){
element.stop().slideToggle(slideDuration);
}
});
}
};
});
回答by Peter
@GFoley83This helped me out a lot thanks! I'm a newbie, so not sure if this is the right way to add a suggestion to help, sorry if it's not. I'm also no expert, so i'm happy for my suggestion to be improved.
@GFoley83这对我帮助很大,谢谢!我是新手,所以不确定这是否是添加建议以提供帮助的正确方法,如果不是,抱歉。我也不是专家,所以我很高兴我的建议得到改进。
I needed the item to start hidden and the ng-init didn't seem to do anything. So, I've added a fourth box with an attribute set to start hidden
我需要该项目开始隐藏,而 ng-init 似乎没有做任何事情。因此,我添加了第四个框,其属性设置为隐藏
Using the code @GFoley83 provided I have an additional attribute "start shown" added to the div which will be toggled.
使用代码@GFoley83,前提是我将一个附加属性“开始显示”添加到将被切换的 div 中。
<input type="button" value="Toggle Fourth" ng-click="box4=!box4">
<div class="div1" data-slide-toggle="box4" data-start-shown="false">
<p>This is 4 section and starts hidden</p>
</div>
The directive has also been updated and now has a check on this new attribute.If it's passed false, we'll hide - otherwise it will continue as before and start by showing the item.
该指令也已更新,现在对这个新属性进行检查。如果传递 false,我们将隐藏 - 否则它将像以前一样继续并从显示项目开始。
return { restrict: "A", scope: { isOpen: "=slideToggle" // attribute }, link: function (scope, element, attr) { var slideDuration = parseInt(attr.slideToggleDuration, 10) || 200; if (attr.startShown=="false") { element.hide(); } scope.$watch('isOpen', function (newVal, oldVal) { if (newVal !== oldVal) { element.stop().slideToggle(slideDuration); } }); } };
Plunker updated : http://plnkr.co/edit/WB7UXK?p=preview
Plunker 更新:http://plnkr.co/edit/WB7UXK?p=preview
回答by evoratec
After trying the solution of Peter i can see that directives below slideToggle cannot acces to parent scope. This is my solution.
在尝试了 Peter 的解决方案后,我可以看到 slideToggle 下面的指令无法访问父作用域。这是我的解决方案。
evoapp.directive('slideToggle', function() {
return {
restrict: 'A',
scope: false ,
link: function(scope, element, attr) {
var slideDuration = parseInt(attr.slideToggleDuration, 10) || 200;
var toggle = attr.toggle ;
scope.$watch(toggle, function(newVal,oldVal){
if(newVal !== oldVal){
element.stop().slideToggle(slideDuration);
}
});
}
};
});