在AngularJS应用程序中,我有一个HTML控件,它通过ng-model指令绑定到js变量。例如:
<input type="text" ng-model="myVar" ng-change="aFunction()" />
我想在myVar从ng-model更改其值之前执行aFunction,因为我需要在aFunction上使用myVar的当前值。
我一直在寻找方法来做或澄清关于Angular指令的执行顺序,但还没有找到一个好的答案。有什么想法吗?
答案 0 :(得分:2)
要在模型更改之前执行函数,请使用指令将$parser
添加到ngModelController
:
angular.module("myApp").directive("preChange", function () {
return {
require: "ngModel",
link: function(scope,elem,attrs,ngModelCtrl) {
ngModelCtrl.$parsers.push(function(value) {
scope.$eval(attrs.preChange, {$newValue: value});
return value;
})
}
}
});
上述指令向$parser
添加ngModelController
,pre-change
执行由$newValue
属性定义的AngularJS表达式。新值显示为<input type="text" ng-model="myVar" pre-change="aFunction(myVar,$newValue)" />
。
用法:
$parsers
来自文档:
$newValue
每当控件从DOM读取值时,作为管道执行的函数数组。函数按数组顺序调用,每个函数都将返回值传递给下一个。最后一个返回值将转发到$ validators集合。
- AngularJS ngModelController API Reference -- $parsers
pre-change
是一个全局变量(意味着它会在使用预更改的任何内容中存储和替换它的值)吗?`
使用指令的父作用域评估$newValue
Angular Expression定义的Expression Binding。变量&
作为本地名称注入,由将本地名称映射到值的对象定义。
来自文档:
&#39;隔离&#39; scope object hash定义了一组从指令元素的属性派生的局部范围属性。这些本地属性对于模板的别名值很有用。对象哈希中的键映射到隔离范围上的属性名称;这些值通过匹配指令元素的属性来定义属性如何绑定到父作用域:
&attr
或<my-component my-attr="count = count + value">
- 提供了在父作用域的上下文中执行表达式的方法。如果未指定attr名称,则假定属性名称与本地名称相同。给定{ localFn:'&myAttr' }
和隔离范围定义范围:count = count + value
,隔离范围属性localFn将指向increment($amount)
表达式的函数包装器。 通常需要通过表达式将数据从隔离范围传递到父范围。这可以通过将局部变量名称和值的映射传递到表达式包装器fn来完成。例如,如果表达式为localFn({$amount: 22})
,那么我们可以通过将localFn称为count = count + $amount
来指定金额值。
或表达式可以是$
。
- AngularJS Comprehensive Directive API -- Scope。
作为惯例,我更喜欢用request.session['thing'] = instance
为本地名称添加前缀,以便将它们与普通范围变量区分开来。
答案 1 :(得分:1)
在$compile
文档中,根据优先级对指令执行顺序进行了解释。只需创建一个优先级高于ng-model
s的指令,然后您的指令的预链接函数将在ng-model
之前执行。
答案 2 :(得分:1)
你可以考虑使用ng-focus来执行一个函数,将焦点中的值存储到另一个范围变量中吗?
<body ng-app="focusApp">
<div ng-controller="focusCtrl">
<div>
<input ng-focus='beforeChangeFunction(myVar)' type="text" ng-model="myVar" >
</div>
<div>
original value: {{originalValue}}
</div>
<div>
dynamic value: {{myVar}}
</div>
</div>
</body>
使用简单的功能:
var app = angular.module('focusApp', [])
app.controller('focusCtrl', function ($scope) {
$scope.beforeChangeFunction = function(preEdit){
$scope.originalValue = preEdit
}
})