【问题标题】:Ignore debounce when we switch files切换文件时忽略去抖动
【发布时间】:2017-10-11 19:58:00
【问题描述】:

我制作了一个非常基本的plunker,它模仿了文本编辑器发生的情况:我们可以在file1file2 之间切换并编辑它们的内容。修改内容会触发changeFile,但我想设置一个debounce

<!DOCTYPE html>
<html ng-app="plunker">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
  </head>
  <body ng-controller="contentCtrl">
    <div ng-repeat="file in files track by $index">
        <input class="item" ng-model="file.name" ng-click="goFile(file)" ng-readonly="true" style="border: none; cursor: pointer"/>
    </div>
    <br/>
    <textarea ng-change="changeFile(file)" ng-model="file.body" ng-model-options="{ debounce: 2000 }"></textarea>
    <div id="console">Recorded:<br/></div>
    <script>
      var app = angular.module('plunker', []);
      app.controller('contentCtrl', ['$scope', function ($scope) {
        $scope.files = [{name: "file1", body: "body1"}, {name: "file2", body: "body2"}]
        $scope.file = $scope.files[0]

        $scope.goFile = function (file) {
          $scope.file = file
        }

        $scope.changeFile = function (file) {
          document.getElementById("console").innerHTML += file.body + "<br/>"
        }
      }]);
    </script>
  </body>
</html>

这里的问题是,刚刚修改了一个文件的内容,很快如果我们切换到另一个文件,修改将不会被考虑在内;它不会显示在控制台中。那不是我想要的。无论debounce 是否完成,我都希望切换到另一个文件会触发changeFile

有谁知道如何修改代码来实现这一点?

【问题讨论】:

    标签: javascript angularjs debouncing debounce


    【解决方案1】:

    您可以做的是将debounce 更改为$timeout,因为debounce 的问题是它不会将值应用于范围,直到时间结束。

    Plunker

    var app = angular.module('plunker', []);
    
    app.controller('contentCtrl', ['$scope', '$timeout', function($scope, $timeout) {
    
      $scope.files = [{
        name: "file1",
        body: "body1"
      }, {
        name: "file2",
        body: "body2"
      }]
      $scope.file = $scope.files[0]
    
      $scope.goFile = function(file) {
        $scope.file = file
        $scope.selectedItem = file
      }
    
      $scope.changeFile = function(file, time) {
        if (file.timeout) {
          $timeout.cancel(file.timeout);
        }
        file.timeout = $timeout(function() {
          document.getElementById("console").innerHTML += file.body + "<br/>"
          console.log(file.name + " changed: " + file.body);
        }, time)
    
      }
    
    }]);
    <!DOCTYPE html>
    <html ng-app="plunker">
    
    <head>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
    </head>
    
    <body ng-controller="contentCtrl">
      <div ng-repeat="file in files track by $index" ng-class="{selected : selectedItem === file}">
        <input class="item" ng-model="file.name" ng-click="goFile(file)" ng-readonly="true" style="border: none; cursor: pointer" />
      </div>
      <br/>
      <textarea ng-change="changeFile(file,2000)" ng-model="file.body"></textarea>
      <div id="console">Recorded:<br/></div>
    </body>
    
    </html>

    我添加了通过您想要去抖动的时间量的功能,以便您可以在$scope.changeFile 函数中添加一行,以便在更改文件时立即更新。

    【讨论】:

    • 您的解决方案的一个问题是,当我们切换文件时,它总是触发changeFile,即使没有内容更改。您有什么想法可以有效地改进这一点吗?
    • @SoftTimur 您可以从$scope.goFile 中删除$scope.changeFile($scope.file, 0); 但这意味着如果您更改了值然后快速更改文件将会有延迟
    • 太棒了...This solution 正是我想要的。所以它只会在 2 秒内没有新更改时触发 changeFile,并且所有文件中的所有先前更改都会被考虑在内...谢谢...
    • @SoftTimur 没问题,我已经更新了问题中的代码以删除该行。
    • 等等...我想我还需要一种输出:我想记录file1 changed: body1abcfile2 changed body2efgfile1 changed body1abcdefgfile2 changed body2efghijk等...一行日志在更改后 2 秒结束或更改后文件切换时生成。如果只是切换文件而没有任何更改,我不想要日志。你能帮我实现吗?延迟不是问题,但我希望没有丢失任何日志...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 2015-04-12
    • 1970-01-01
    • 2013-03-11
    相关资源
    最近更新 更多