Angular js ng-change事件

时间:2014-04-07 05:34:33

标签: javascript jquery html angularjs

我在我的应用程序中使用角度js。在ng-change事件中,我调用webservice并基于呈现html的响应。但是这里的ng-change调用过于频繁,我们快速键入,导致浏览器等待。这不是chrome和mozilla的问题。谁能在这帮助我?

6 个答案:

答案 0 :(得分:6)

您可以使用超时并等待用户在拨打服务器之前完成输入:

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

请注意,使用Angular的$timeout(而非setTimeout/clearTimeout)将为您处理Angular摘要周期(因此您无需亲自调用$apply()$digest())。

答案 1 :(得分:5)

我也遇到了类似的问题,我想实施一次去抖动搜索。经过一番重击之后,这就是我的所作所为:

这是我的输入字段,标有ng-model指令

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

请注意我还包括了ng-model-options =&#34; {debounce:500}&#34;。它以指定的毫秒数去除底层模型的更新。 请参阅ng-model-options指令here的文档。

现在,我添加了一个这样的$ watch:

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

请参阅$ watch here的文档。它注册一个事件监听器,监听作为第一个参数传递的表达式的任何变化。在这种情况下,&#39; searchText&#39;,这是与我的输入字段相关联的模型。

ng-model-options中提到的去抖动,对“搜索文本”的更新进行了辩护。模型,因此,它负责debouncing ajax调用(在我的情况下)。

希望它有所帮助。 :)

答案 2 :(得分:2)

你想要使用去抖模式,按照以下几行:

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

这样做是在最后一次调用之后发送请求333毫秒。如果您在每次更改时都调用它,这将在请求之间添加一点间距,从而优化应用程序。

333是Google用于文本输入的内容,您可以随意使用这些值并查看最适合您的内容。

答案 3 :(得分:2)

您可以使用$watch$watchCollection来实现直播活动。

在我的理解和用法中,$ watch和$ watchCollection比ng-change安静有效。

这是一个很好的例子,

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

内部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=""/>

$watch$watchCollection都会继续查看任何更改的输入字段。一旦进行任何更改,触发器将被调用,这将永远不会死。希望这会有所帮助。

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

你应该使用去抖方法 - 当你输入太频繁时,服务器不应该点击。当您停止键入并发生超时时,请求应发送到服务器。您可以使用Underscore Debounce feature或在此处进行自定义实施:

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

此处的请求仅在您停止输入时发送,并且在此之后发生500ms超时。

另一种实施方式(使用愤怒的方法):

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

另外一种方法是使用更通用的方法使用自定义指令和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)
            });
        }
    }
});