AngularJS:attrs.$观察第一次后不开火
在小提琴中,如果您第一次单击submit按钮,请注意,AngularJS:attrs.$观察第一次后不开火,angularjs,angularjs-directive,angularjs-scope,Angularjs,Angularjs Directive,Angularjs Scope,在小提琴中,如果您第一次单击submit按钮,请注意,正确聚焦。在随后的单击中,焦点不再设置 我注意到当submit()更改isFocused时,$observe回调没有被触发,所以我添加了一个blur侦听器来显式重置变量,但这也没有帮助 我如何使焦点集中在提交上 编辑:。改为使用$watch,因为我希望它能够处理任意表达式我认为您无法观察focusOn属性,因为它实际上不作为指令的属性存在。当您执行时,关注的实际上是您的指令名 请尝试以下方法: HTML <div ng-app='foo
正确聚焦。在随后的单击中,焦点不再设置
我注意到当submit()
更改isFocused
时,$observe
回调没有被触发,所以我添加了一个blur
侦听器来显式重置变量,但这也没有帮助
我如何使焦点集中在提交上
编辑:。改为使用
$watch
,因为我希望它能够处理任意表达式我认为您无法观察focusOn
属性,因为它实际上不作为指令的属性存在。当您执行
时,关注的实际上是您的指令名
请尝试以下方法:
HTML
<div ng-app='foo'>
<form ng-controller='FormCtrl' ng-submit='submit()'>
<input focus-on focused='isFocused' />
<button>Submit</button>
</form>
</div>
我创建了一个focused
属性,将isFocused
属性绑定到指令作用域(我可以将其命名为focusOn
,但我想拥有
会很奇怪)
更新的JSFIDLE
更新:我将属性名称从ng model
更改为focused
,因此它更有意义。如果您观看该元素,您会注意到当触发模糊回调时,focus on
属性没有设置为false。原因是blur
函数超出angular的范围,因此它不知道您在其内部所做的更改
要使angular了解更改,您需要将所有更改包装在对的调用中
对此不确定,因为我需要ng模型来表示表单字段中的实际值。比如说,当ng model='email'时,执行$scope.email=true是没有意义的。哦,我明白了。好的,您可以为属性选择另一个名称。我刚刚将属性名称更改为聚焦
。现在更有意义了。我很清楚这个$apply的东西,但在我尝试其他东西时完全忽略了它。谢谢+1.斑点很好。尽管如此,我仍然不确定$observe方法是否是最好的,在我看来$broadcast/$on在更短、更易于维护的代码中提供了相同的结果。如果我错过了一个原因,我愿意相信@mikel我实际上偷了$observe这个东西,但看到我的最终解决方案是使用$watch:。我更喜欢不使用事件,因为我遇到过几个实例,当事情因为不匹配的事件字符串而无声地失败时。当变量未定义时,至少会看到错误。另外,我不想硬编码事件字符串,因为除了提交空表单之外,我还有其他原因需要关注字段。似乎不适合在这里使用事件,这很公平。不管怎么说,看到不同的方法很有趣。你可以看看这个实现是件好事,它似乎是实现ngBlur和ngFocus的好方法。
app.directive('focusOn', function () {
return {
scope: { focused: '=' },
link: function(scope, element) {
scope.$watch('focused', function (newValue) {
console.log('$watch', newValue)
if (newValue) {
element[0].focus();
}
});
element.bind('blur', function () {
scope.focused = false;
scope.$apply(); // required so that the scope is updated correctly.
console.log('blur');
});
}
};
});
app.controller('FormCtrl', function ($scope) {
$scope.submit = function () {
$scope.isFocused = true;
console.log('submit');
};
});
element.bind('blur', function () {
scope.$apply(function() {
scope.isFocused = false;
console.log('blur');
});
});