我有一个“可切换”项目列表。单击“toggleable”元素时,元素将使用ng-show指令进行扩展。如果单击内部项目保持打开状态,但如果您单击其他位置,该项目将收缩。
我实现它的方法是使用一个指令,它公开一个绑定属性isOpen。 isOpen的值在指令链接函数中更改。在元素单击时,isOpen的值设置为true,并将close函数绑定到$ document click事件。如果在元素外部单击,则调用close函数,将isOpen设置为false并取消绑定文档单击事件。
这适用于此指令的单个实例,但如果引入了两个或更多实例,则除了第一次单击之外的每个元素的close函数都无法将相应的isOpen属性设置为false。
这是一个Plunker:http://plnkr.co/edit/ZNTRc2uL73kFZJmYOvhh?p=preview
该指令如下所示:
app.directive('myToggle', ['$document', function ($document) {
var closeToggle = null;
return {
restrict: 'A',
scope: { isOpen: '=myToggle' },
link: link
};
function link(scope, element, attributes) {
scope.$on('$locationChangeSuccess', function () { if (closeToggle) closeToggle(); });
element.bind('click', function() {
closeToggle = function(event) {
if (event)
if (element.parent().find(event.target).length != 0 && scope.isOpen)
return false;
$document.unbind('click', closeToggle);
scope.$apply(function () {
scope.isOpen = false;
});
closeToggle = angular.noop;
};
if (!scope.isOpen) {
scope.$apply(function() {
scope.isOpen = true;
});
$document.bind('click', closeToggle);
}
});
};
}]);
app.directive('myToggleCard', [function () {
// Usage:
//
// Creates:
//
var directive = {
link: link,
restrict: 'E',
template: '<a data-my-toggle="isOpen" data-ng-show="!isOpen" href="">ClickMe</a><div data-ng-if="isOpen"> Extra Content </div>',
replace: true,
scope: {
}
};
return directive;
function link(scope, element, attrs) {
scope.isOpen = false;
}
}]);
并且html看起来像这样:
<div>
<div>
<my-toggle-card></my-toggle-card>
<my-toggle-card></my-toggle-card>
<my-toggle-card></my-toggle-card>
<my-toggle-card></my-toggle-card>
</div>
</div>
答案 0 :(得分:1)
玩弄plunker并记住一篇文章,我在范围,提升和函数声明上阅读了几天,我明白使用函数表达式而不是函数声明可能会导致问题。
我猜测即使它们在同一指令的不同实例中声明,closeToggle函数表达式也会被提升到更高的范围,因此在指令之间共享。
更换
closeToggle = function(event) {
带
functions closeToggle(event) {
解决了这个问题。 (Plunker:http://plnkr.co/edit/N6p4eU08dfyLLSeotw5S?p=preview)
我希望我得到了解决这个问题的原因。我并非100%确定我已经掌握了这些概念,所以欢迎另一个更完整的答案。
答案 1 :(得分:1)
在原始的plunker中,这会使您的函数具有全局范围,因此具有此指令的所有元素都在执行它:
closeToggle = function(event) {
如果您将此功能的范围仅仅与您的指令隔离,就像这样,它将正常工作
var closeToggle = function(event) {