简体   繁体   English

Angular js ng-change事件

[英]Angular js ng-change event

I am using angular js in my application. 我在我的应用程序中使用角度js。 where in ng-change event i am calling webservice and based on the response rendering the html. 在ng-change事件中,我调用webservice并基于呈现html的响应。 but here in ng-change calls too frequently where we type fastly which causes browser to wait. 但是这里的ng-change调用过于频繁,我们快速键入,导致浏览器等待。 this is not a problem in chrome and mozilla. 这不是chrome和mozilla的问题。 can anyone help me here? 有人能帮我一下吗?

You could use a timeout and wait for the user to have finished typing before making a call to the server: 在调用服务器之前,您可以使用超时并等待用户完成输入:

<input type="text" ng-model="some.thing" ng-change="fetchData()" />

app.controller('someCtrl', function ($scope, $timeout) {
    var fetchDataDelay = 500;   // milliseconds
    var fetchDataTimer;

    $scope.fetchData = function () {
        $timeout.cancel(fetchDataTimer);
        fetchDataTimer = $timeout(function () {
            // make expensive call to the server...
        }, fetchDataDelay);
    };
});

Note that using Angular's $timeout (instead of setTimeout/clearTimeout ) will take care of the Angular digest cycle for you (so you don't have to bother yourself with manually calling $apply() or $digest() ). 请注意,使用Angular的$timeout (而不是setTimeout/clearTimeout )将为您处理Angular摘要周期(因此您不必为手动调用$apply()$digest()而烦恼。

I also faced a similar problem, I wanted to implement a debounced search. 我也面临类似的问题,我想实施一个去抖动搜索。 After a bit of headbanging, this is what I did : 经过一番争吵之后,这就是我的所作所为:

Here is my input field marked with ng-model directive 这是我的输入字段,标有ng-model指令

<input ng-model="searchText" ng-model-options="{ debounce: 500 }" type="text" class="form-control" placeholder="Search...">

Please observe that I also included an ng-model-options="{ debounce: 500 }". 请注意我还包括ng-model-options =“{debounce:500}”。 It debounces the update to the underlying model by the specified number of milliseconds. 它以指定的毫秒数去除底层模型的更新。 Please refer to the documentation for ng-model-options directive here . 请参考NG-模型选项指令的说明这里

Now, I added a $watch like this : 现在,我添加了一个这样的$ watch:

    $scope.$watch('searchText', function(newValue) {
        // expensive ajax call
    });

Please refer to the documentation of $watch here . 请参考$表的文档在这里 It registers an event listener listening for any change in the expression passed as its first argument. 它注册一个事件监听器,监听作为第一个参数传递的表达式的任何变化。 In this case 'searchText', which is the model associated with my input field. 在这种情况下,'searchText',这是与我的输入字段相关联的模型。

The debounce mentioned in the ng-model-options, debounces the update to the 'searchText' model and hence, it takes care of debouncing the ajax call(in my case). 在ng-model-options中提到的debounce消除了对'searchText'模型的更新,因此,它负责对ajax调用进行去抖(在我的情况下)。

Hope it helps. 希望能帮助到你。 :) :)

You'll want to use a debounce pattern, along these lines: 你会想要使用去抖模式,沿着这些方向:

.factory('myFactory', function($http) {
  var debounce;
  var doRequest = function() {
    clearTimeout(debounce);
    setTimeout(function() {
      // Make HTTP call here
    }, 333);
  };
  return {
    doRequest: doRequest
  };
});

What this does is send the request 333 milliseconds after the last time it's been called. 这样做是在最后一次调用之后 333毫秒发送请求。 If you're calling it on every change, this will add a little spacing between requests, optimizing the application. 如果您在每次更改时调用它,这将在请求之间添加一点间距,从而优化应用程序。

333 is what Google uses for text input, feel free to play around with the values and see what works best for you. 333是Google用于文本输入的内容,您可以随意使用这些值并查看最适合您的内容。

You can use $watch or $watchCollection to achieve the live event. 您可以使用$watch$watchCollection来实现直播活动。

In my understanding and usage $watch and $watchCollection is quiet efficient than ng-change. 在我的理解和使用中,$ watch和$ watchCollection比ng-change安静有效。

Here is a good example, 这是一个很好的例子,

$scope.$watchCollection('[some_modelname,someother_modelname]',function(){
            alert('Changed the input value!');
        });
$scope.$watch('some_modelname',function(){
            alert('Changed the input value!');
        });

Inside HTML, 在HTML中,

<input type="text" ng-model="some_modelname" id="someid" name="somenameifneeded" value=""/>
<input type="text" ng-model="someother_modelname" id="someotherid" name="somenameifneeded" value=""/>

Both $watch and $watchCollection keep looking at the input field for any changes. $watch$watchCollection持续查看任何更改的输入字段。 Once made any changes the trigger will be called and this will keep never die.. Hope this helps. 一旦进行了任何更改,触发器将被调用,这将永远不会死。希望这会有所帮助。

在angularjs 1/3你有debounce作为ng-options这里是一个例子,所以你可以将它添加到你的ng-change,它会为你管理它

ng-model-options="{debounce: {'default': 500} }

You should use debounce approach - while you are typing too frequently the server should not bit hit. 你应该使用debounce方法 - 当你输入太频繁时,服务器不应该点击。 When you stop typing and timeout occurs the request should be sent to the server. 当您停止键入并发生超时时,请求应发送到服务器。 You can either use Underscore Debounce feature or make a custom implementation here: 您可以使用Underscore Debounce功能或在此处进行自定义实施:

$scope.loadData = function () {
   var loadThrottle;
   clearTimeout(loadThrottle);
   loadThrottle = setTimeout(function () {
       $scope.$apply(function () {
           $scope.getData();
       });
   }, 500);
};

The request here will be sent only if you stop typing and 500ms timeout occurs after that. 此处的请求仅在您停止输入时发送,并且在此之后发生500ms超时。

Another implementation (using angularized approach): 另一种实现(使用愤怒化方法):

$scope.loadData = function(timeout) {
     $scope.counter += 1;
     var counter = $scope.counter;
     $timeout(function(){
         if (counter === $scope.counter) {
             $scope.getData();
             $scope.counter = 0;
         }
     }, timeout ? timeout : 500);
}

And also alternative is using more generic approach with custom directive and Underscore something like that: 另外一种方法是使用更通用的方法和自定义指令和Underscore之类的东西:

app.directive('changeTimeout', function() {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
            angular.forEach(ctrl.$viewChangeListeners, function(listener, index) {
                ctrl.$viewChangeListeners[index] = _.debounce(function() {
                    scope.$apply(attrs.ngChange);
                }, attrs.changeTimeout || 0)
            });
        }
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM