javascript AngularJS - 模糊 + 改变?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20441779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 18:30:21  来源:igfitidea点击:

AngularJS - Blur + Changed?

javascriptangularjsangularjs-directive

提问by Roger Johansson

What is the easiest way to combine ng-changed and ng-blur?

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

I've found this post: How to let ng-model not update immediately?

我找到了这篇文章:如何让 ng-model 不立即更新?

However, this does no longer work in angluar 1.2+ Is there any way to achieve the same behavior?

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

I guess I have to store a copy of the old value myself and compare the new value to that on blur if I try to do the same, or is there any easier way ?

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

采纳答案by Roger Johansson

This does what I want. It stores the value on focus, and compares it to the new value on blur, if changed, it triggers the expression in the attribute.

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

 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);
                        });         
                    });
                }
            };
        });

usage:

用法:

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

回答by Niels Steenbeek

Use ng-model options. Like this, ng-changewill only trigger when the input is blurred.

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

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

回答by Michael

How about this solution. Works for me:

这个解决方案怎么样。对我有用:

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

回答by Yogesh Manware

I am using AngularJs 1.2.x and stumbled upon the ng-change issue of firing on each change. ng-blur can be used but it fires even though there is no change in the value. So both cannot be used efficiently.

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

With Angularjs 1.3.x, things are easier using ng-model-optionslike below

使用 Angularjs 1.3.x,使用ng-model-options下面的方法更容易

to invoke change function "onBlur"

调用更改功能“onBlur”

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

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

And

to delay invocation of change function by 500ms

将更改功能的调用延迟 500 毫秒

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

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

Now coming to back to the question of getting such things with AngularJs 1.2.x

现在回到用 AngularJs 1.2.x 获得这些东西的问题

to invoke change function "onBlur"

调用更改功能“onBlur”

html

html

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

<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)" />

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

JS

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;
}

to delay invocation of change function by 500ms

将更改功能的调用延迟 500 毫秒

html

html

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

<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"/>

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

JS

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;
}

plnkrs for both approaches are

两种方法的 plnkrs 是

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

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

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

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

回答by Chris Montgomery

how about this plunkr?

这个 plunkr怎么

using angular's built in ng-blur, update your "persisted value" on blur

使用 angular 的内置ng-blur,更新模糊上的“持久值”

<input type="text" ng-model="boxValue" ng-blur="doneEditing(boxValue)">

when saving, verify the value is different

保存时,验证值不同

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

There is no special option on ng-blurfor pre-checking equality that I'm aware of. A simple ifseems to do the trick

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

回答by manikanta

Newer versions of AngularJS (now in 1.3 beta) supports this natively. See my answer here

较新版本的 AngularJS(现在是 1.3 测试版)本身就支持这一点。在这里看到我的答案

回答by Kmeixner

The solution that worked for me was as follows:

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

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

I found this solution here

我在这里找到了这个解决方案

That page says it requires AngularJS version 1.3.0+ . I tested it with AngularJS version 1.5.11 and it works in that version for me.

该页面说它需要 AngularJS 版本 1.3.0+ 。我使用 AngularJS 版本 1.5.11 对其进行了测试,它在该版本中对我有效。

回答by Vaibhav Lokhande

In app.html

在 app.html

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

in app.ts

在 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
    }
}