【问题标题】:textarea $watch scrollheight and scrolltop does not trigger updatetextarea $watch scrollheight 和 scrolltop 不会触发更新
【发布时间】:2014-11-08 02:11:12
【问题描述】:

我正在编写一个简单的 Angular 指令,用于在 textarea 旁边显示行号。但是,由于某种原因,$watch 表达式不会触发更新。代码如下:

    mod.directive('newTextArea', function() {
      return {
        restrict: 'E',
        scope: {
          query: '='
        },
        template:
          '<div>' +
          '  <div ng-style="{height: height}" style="width: 20px; float: left; color: gray; font-family: Courier New; font-size: 14px; overflow: hidden; height: 85px; position: relative; top: 5px;">' +
          '    <div style="position: absolute">' +
          '    <span ng-repeat="line in lines">{{line}}<br></span>' +
          '    </div>' +
          '  </div>' +
          '  <textarea id="query-area" style="overflow-x: scroll; font-family: Courier New; font-size: 14px;">' +
          '  </textarea> {{ lines }}' +
          '</div>',
        controller: function($scope, $attrs, $element) {
          var textarea = document.getElementById('query-area');

          function updateLayout() {
              var st = textarea.scrollTop;
              var h = textarea.scrollHeight;
              $scope.height = h;
console.log(st, h);
              if (st !== undefined && h !== undefined) {
                var start = Math.round(st / 14);
                var stop = Math.round((st + h) / 14);
                $scope.lines = _.range(start+1, stop+1);
            }
          }

          $scope.$watch(
            function() {
              return [textarea.scrollHeight, textarea.scrollTop];
            }, updateLayout, true
          );
        }
      };

文本区域滚动或大小发生变化时,行号应立即更新。知道为什么这不起作用吗?

【问题讨论】:

    标签: javascript angularjs dom textarea


    【解决方案1】:

    观察者在摘要循环期间运行。在文本区域写入不会导致摘要循环开始,因此永远不会执行观察者。

    例如,如果您将 ng-model="something" 添加到 textarea 元素中,它将起作用,此后 Angular 将绑定到一堆事件并在它们触发时在内部触发摘要循环。

    在不依赖其他东西来触发摘要循环的情况下,您可以将$watch 替换为以下内容:

    var listener = function() {
      $scope.$apply(updateLayout);
    };
    
    angular.element(textarea).on('keyup keydown keypress change', listener);
    
    updateLayout();
    
    $scope.$on('$destroy', function () {
      angular.element(textarea).off('keyup keydown keypress change', listener);
    });
    

    演示http://plnkr.co/edit/nIkGyhM75OScU8ZyosyP?p=preview

    【讨论】:

    • 适用于更改文本,但不适用于调整 textarea 的大小。是否可能缺少事件?
    • 这些只是示例事件。但是,不要认为 textarea 有 resize 事件,至少不是在大多数浏览器中实现的。调整大小后发布时可以添加mouseup更新。
    • 好的,就可以了。感谢您的帮助!
    猜你喜欢
    • 2014-07-20
    • 2016-03-10
    • 1970-01-01
    • 2014-12-31
    • 2013-07-21
    • 2015-07-22
    • 1970-01-01
    • 2016-03-07
    • 2013-03-29
    相关资源
    最近更新 更多