textarea $ watch scrollheight和scrolltop不会触发更新

时间:2014-11-08 02:11:13

标签: javascript angularjs dom textarea

我正在编写一个简单的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
          );
        }
      };

一旦滚动textarea或其大小发生变化,行号应立即更新。知道为什么这不起作用吗?

1 个答案:

答案 0 :(得分: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