AngularJS:在ng-model执行之前触发内容

时间:2016-08-25 00:51:09

标签: javascript html angularjs events angularjs-directive

在AngularJS应用程序中,我有一个HTML控件,它通过ng-model指令绑定到js变量。例如:

<input type="text" ng-model="myVar" ng-change="aFunction()" />

我想在myVar从ng-model更改其值之前执行aFunction,因为我需要在aFunction上使用myVar的当前值。

我一直在寻找方法来做或澄清关于Angular指令的执行顺序,但还没有找到一个好的答案。有什么想法吗?

3 个答案:

答案 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添加ngModelControllerpre-change执行由$newValue属性定义的AngularJS表达式。新值显示为<input type="text" ng-model="myVar" pre-change="aFunction(myVar,$newValue)" />

用法:

$parsers

来自文档:

  

$newValue

     

每当控件从DOM读取值时,作为管道执行的函数数组。函数按数组顺序调用,每个函数都将返回值传递给下一个。最后一个返回值将转发到$ validators集合。

- AngularJS ngModelController API Reference -- $parsers

DEMO on JSFiddle

  

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
    }

  })

link to fiddle