AngularJS - 模糊+改变?

时间:2013-12-07 13:16:20

标签: javascript angularjs angularjs-directive

将ng-changed和ng-blur结合起来的最简单方法是什么?

我发现了这篇文章:How to let ng-model not update immediately?

但是,这不再适用于1.2+ 有没有办法实现相同的行为?

我想我必须自己存储一个旧值的副本,并将新值与模糊值进行比较,如果我尝试做同样的事情,或者有更简单的方法吗?

8 个答案:

答案 0 :(得分:44)

使用ng-model options。 像这样,ng-change只会在输入模糊时触发。

<input type="text" 
       ng-model="a.b" 
       ng-model-options="{updateOn: 'blur'}" 
       ng-change="onchange()"/>

答案 1 :(得分:14)

这就是我想要的。 它将值存储在焦点上,并将其与模糊的新值进行比较,如果更改,则会触发属性中的表达式。

 app.directive('changeOnBlur', function() {
            return {
                restrict: 'A',
                require: 'ngModel',
                link: function(scope, elm, attrs, ngModelCtrl) {
                    if (attrs.type === 'radio' || attrs.type === 'checkbox') 
                        return;

                    var expressionToCall = attrs.changeOnBlur;

                    var oldValue = null;
                    elm.bind('focus',function() {
                        scope.$apply(function() {
                            oldValue = elm.val();
                            console.log(oldValue);
                        });
                    })
                    elm.bind('blur', function() {
                        scope.$apply(function() {
                            var newValue = elm.val();
                            console.log(newValue);
                            if (newValue !== oldValue){
                                scope.$eval(expressionToCall);
                            }
                                //alert('changed ' + oldValue);
                        });         
                    });
                }
            };
        });

用法:

 <input ng-model="foo" change-on-blur="someFunc()" />

答案 2 :(得分:4)

这个解决方案怎么样?适合我:

<input ng-init="oldValue = value" ng-model="value"
       ng-blur="oldValue != value && callYourFunc(foo)">

答案 3 :(得分:3)

this plunkr怎么样?

使用ng-blur内置的角度,更新模糊

上的“持久值”
<input type="text" ng-model="boxValue" ng-blur="doneEditing(boxValue)">

保存时,验证值是否不同

$scope.doneEditing = function(v) {
  if (v !== $scope.persistedValue) // only save when value is different
    $scope.persistedValue=v;
}

ng-blur上没有特殊选项来预先检查我所知道的相等性。一个简单的if似乎可以解决这个问题

答案 4 :(得分:3)

我正在使用AngularJs 1.2.x,并偶然发现每次更改触发的ng-change问​​题。可以使用ng-blur,但即使值没有变化也会触发。所以两者都无法有效使用。

使用Angularjs 1.3.x,使用ng-model-options(例如下面的

)可以更轻松地完成任务

调用更改功能&#34; onBlur&#34;

ng-change="ctrl.onchange()" ng-model-options="{updateOn: 'blur'}"

并且

延迟调用变更函数500毫秒

ng-change="ctrl.onchange()" ng-model-options='{ debounce: 500 }'"

现在回到使用AngularJs 1.2.x获取此类内容的问题

调用更改功能&#34; onBlur&#34;

<强> HTML

<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange()" />

<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange(ctrl.a.c)" />

JS

app.directive('sdChangeOnBlur', function() {
  return {
    restrict: 'A',
    scope: {
      sdChangeOnBlur: '&'
    },
    link: function(scope, elm, attrs) {
      if (attrs.type === 'radio' || attrs.type === 'checkbox')
        return;

      var parameters = getParameters(attrs.sdChangeOnBlur);

      var oldValue = null;
      elm.bind('focus', function() {
        scope.$apply(function() {
          oldValue = elm.val();
        });
      })

      elm.bind('blur', function() {
        scope.$apply(function() {
          if (elm.val() != oldValue) {
            var params = {};
            if (parameters && parameters.length > 0) {
              for (var n = 0; n < parameters.length; n++) {
                params[parameters[n]] = scope.$parent.$eval(parameters[n]);
              }
            } else {
              params = null;
            }

            if (params == null) {
              scope.sdChangeOnBlur();
            } else {
              scope.sdChangeOnBlur(params)
            }
          }
        });
      });
    }
  };
});

function getParameters(functionStr) {
  var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
  var params;
  if (paramStr) {
    params = paramStr.split(",");
  }
  var paramsT = [];
  for (var n = 0; params && n < params.length; n++) {
    paramsT.push(params[n].trim());
  }
  return paramsT;
}

延迟调用变更函数500毫秒

<强> HTML

<input type="text" ng-model="name" sd-change="onChange(name)" sd-change-delay="300"/>

OR

<input type="text" ng-model="name" sd-change="onChange()" sd-change-delay="300"/>

<强> JS

app.directive('sdChange', ['$timeout',
  function($timeout) {
    return {
      restrict: 'A',
      scope: {
        sdChange: '&',
        sdChangeDelay: '@' //optional
      },
      link: function(scope, elm, attr) {
        if (attr.type === 'radio' || attr.type === 'checkbox') {
          return;
        }

        if (!scope.sdChangeDelay) {
          scope.sdChangeDelay = 500; //defauld delay
        }

        var parameters = getParameters(attr.sdChange);

        var delayTimer;
        elm.bind('keydown keypress', function() {
          if (delayTimer !== null) {
            $timeout.cancel(delayTimer);
          }

          delayTimer = $timeout(function() {
            var params = {};
            if (parameters && parameters.length > 0) {
              for (var n = 0; n < parameters.length; n++) {
                params[parameters[n]] = scope.$parent.$eval(parameters[n]);
              }
            } else {
              params = null;
            }

            if (params == null) {
              scope.sdChange();
            } else {
              scope.sdChange(params)
            }
            delayTimer = null;
          }, scope.sdChangeDelay);

          scope.$on(
            "$destroy",
            function(event) {
              $timeout.cancel(delayTimer);
              console.log("Destroyed");
            }
          );
        });
      }
    };
  }
]);

function getParameters(functionStr) {
  var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
  var params;
  if (paramStr) {
    params = paramStr.split(",");
  }
  var paramsT = [];
  for (var n = 0; params && n < params.length; n++) {
    paramsT.push(params[n].trim());
  }
  return paramsT;
}

两种方法的关键是

http://plnkr.co/edit/r5t0KwMtNeOhgnaidKhS?p=preview

http://plnkr.co/edit/9PGbYGCDCtB52G8bJkjx?p=info

答案 5 :(得分:2)

较新版本的AngularJS(现在在1.3 beta版中)本机支持此版本。见my answer here

答案 6 :(得分:1)

对我有用的解决方案如下:

<input id="fieldId" type="text"
ng-model="form.fields.thisField"
ng-model-options="{ updateOn: 'blur' }"
ng-change="form.save()" />

我找到了这个解决方案here

该页面说它需要AngularJS版本1.3.0+。我使用AngularJS 1.5.11进行了测试,它适用于我的版本。

答案 7 :(得分:0)

在app.html中

<input type="text" name="name" ng-model="$ctrl.user.name" ng-blur="$ctrl.saveChanges()" ng-change="$ctrl.onFieldChange()"/>

在app.ts中

 public onFieldChange() {
    this.isValuesModified = true;
}

//save changes on blur event
public saveChanges() {
    //check if value is modified
    if(this.isValuesModified){

     //Do your stuff here
    }
}