我是一个DOM元素(绑定到一个表)。我是基于ngShow的选项卡控件的下游子代。我住在第二个标签上。当页面被渲染时,我存在,但我还不是真的可见。
当我的非直系父母看到它的ngShow表达式变为真时,我想以某种方式得到通知。
这可能吗?我想避免在我自己以外的任何地方添加代码 - 例如,我宁愿不在某个地方更改选项卡中添加代码。我宁愿有办法注册,通过ngShow / ngHide绑定的最外层容器的变化来查明我的可见性变化。可以这样做吗?
答案 0 :(得分:21)
由于指令中有可用的范围,您可以使用它来监视可见性的变化:
scope.$watch(function() { return element.is(':visible') }, function() {
// Do whatever should happen when the visibility changes
});
这可以避免轮询可见性,这可能会影响性能。当然,这假定范围由任何导致可见性改变的因素应用。我已经在我自己的指令中尝试过,但与ngShow / ngHide无关。
信用到期的信用:这最初是由我提出的(不是我):
https://groups.google.com/d/msg/angular/w7Gxa5M_17M/koYCZnsobawJ
编辑2014-02-24
几个月后重新回答这个答案,我注意到这个有效,但会慢慢减慢你的消化周期。最佳做法是不要使用诸如此类的昂贵功能进行脏检查。请谨慎使用!
答案 1 :(得分:8)
我找到的最佳方式:
link: function (scope, element, attr) {
attr.$observe('ngShow', function (expr) {
scope.$watch(function () {
return $parse(expr)(scope);
}, function (value) {
console.log(value)
})
});
}
祝你好运!
答案 2 :(得分:4)
我用指令做了这个:
Elemement:
<test-directive ng-show="showMe" show-model="showMe"></test-directive>
指令:
app.directive('testDirective', function() {
return {
restrict: 'E',
scope: {
showModel: "=?",
},
controller: function($scope) {
if (angular.isDefined($scope.showModel)) {
$scope.$watch('showModel', function(newValue, oldValue) {
// Do stuff
});
}
}
}
});
因此,我们的想法是将$ watch放在与ng-show链接的同一个变量上。
答案 3 :(得分:3)
我唯一能想到的就是创建一个循环指令来查看元素是否可见。类似的东西:
angular.module('testModule', [])
.directive('onVisible', ['$timeout', function($timeout) {
return {
restrict: 'A',
scope: {
onVisible: '&'
},
link: function(scope, element, attrs) {
var checkVisibility = function() {
if (element.is(':visible')) {
scope.onVisible();
} else {
$timeout(checkVisibility, 100);
}
};
$timeout(checkVisibility, 100);
}
};
}]);
当然,如果每次元素变得可见时都需要执行它,你还需要注意元素转换回隐藏。
编辑:这假设您有jQuery可用。
答案 4 :(得分:3)
另一种可能的方法是使用$ broadcast。选择标签后,您可以广播活动
$scope.$broadcast('secondTabSelected');
您可以在控制器内处理此事件并进行进一步处理。
$scope.$on('secondTabSelected', function(e){
// do something awesome.
})
每次选项卡可见时,都会通知您。只执行一次,你可以做
var firstTimeSelected = false;
$scope.$on('secondTabSelected', function(e){
if(firstTimeSelected){
firstTimeSelected = true;
// do something awesome
}
})