我正在尝试使用ng-show
和$timeout
来实现一个延迟容器显示的指令。
这是我的指令的样子:
angular.module('myApp')
.directive('delay', function($timeout) {
return {
template: '<div ng-show="showIt" ng-transclude></div>',
replace: false,
transclude: true,
scope:true,
restrict: 'A',
link: function postLink(scope, element, attrs) {
$timeout(function() {
scope.showIt = true;
}, attrs.delay);
}
};
});
然后,我会在我的视图中使用它
<div delay="1000">
<intput type="text" ng-model="myText"/>
</div>
到目前为止,延迟有效。是的,我很自豪。但是,myText
不再可以从控制器访问,因为父作用域不可见它。我尝试将范围更改为:
scope: {
myText: '='
}
建立双向数据绑定......但没有任何成功。
使用指令实现我想要实现的最简单的方法是什么?非常感谢!
编辑:黄金法则
非常感谢GregL的回答!
最好的方法是简单地将我的ng模型包装在一个对象中,以利用点表示法来避免将ng模型绑定到子范围。子范围使用原型继承来查找其值,因此当在子范围中设置了值时,它不再查找父范围。
答案 0 :(得分:3)
解决这个问题的最佳方法是牢记我所谓的“AngularJS黄金法则”:
始终在ng-model表达式中使用点/句点(。)。
这样,您将把属性写入正确范围内的正确对象。
但是,如果你真的想让它工作,你可以做一个指令,利用链接函数的transclude
参数来对正确的范围进行手动转换。
sample.directive('delay', function($timeout) {
return {
template: '<div ng-show="showIt"></div>',
replace: false,
transclude: true,
scope: {},
restrict: 'A',
link: function postLink(scope, element, attrs, nullCtrl, transclude) {
var transcludeScope = scope.$parent;
transclude(transcludeScope, function(clone) {
element.find('div[ng-show]').append(clone);
});
$timeout(function() {
scope.showIt = true;
}, attrs.delay);
}
};
});
这会将<div ng-show="showIt">
的内容范围设置为delay
指令所在元素的范围。它还具有隔离范围的优点,因此您可以在任何地方使用多个实例。
答案 1 :(得分:0)
试试{scope: false}
。您正在使用delay
指令创建自己的范围。
或者
link: function(scope, element) {
var showing = true;
$timeout(function() {
if (showing) {
element.hide();
} else {
element.show();
}
showing = !showing;
}, delay)
}