Textarea ng-bind,其中value有前缀和后缀

时间:2016-06-24 08:55:27

标签: javascript html angularjs

在我看来,我正在努力完成一些相当简单的事情。当使用类似文本输入的东西时也是如此。我正在尝试在textarea上创建模型绑定,其中当用户键入时,值显示带有前缀和后缀。前缀和后缀是引号:

“My awesome quote”

问题是,我目前正在使用ng-model,我当然不能使用它。我正在考虑绑定到变量,保持没有前缀和后缀的值,然后观察该变量。当具有原始值的变量随后发生变化时,我会在范围上将带有pre和suffix的值写入另一个变量。然后,当用户输入时,该变量将显示在textarea中。唯一的问题是,与输入字段不同,textarea没有值属性。

这甚至可能吗?

修改

如果我在哪里用输入文本字段实现这一点,我将创建一个名为A的变量,以保存用户输入时更改的原始值。 当A发生变化时,我会接受原始值,在其周围加上引号并将该新值存储在另一个变量中,也在范围内。这个新变量叫做B

输入字段将在A变量上使用ng-bind,并使用输入字段值属性显示B变量中的内容。如下所示:

<input type="text" ng-bind="A" value="{{B}}">

我现在没有时间创作一个小提琴,但我会在本周晚些时候尝试这样做。上面的描述都是理论上的,因为我还没有测试过它。

2 个答案:

答案 0 :(得分:1)

<强>更新

所以我使用了焦点和模糊来删除和添加引号,它在使用textarea时不会生效但是它会起作用

angular.module('myApp', [])
  .controller('demoCtrl', ['$scope',
    function($scope) {
      $scope.myModel = '';

      $scope.removeQuotes = function() {
        $scope.myModel = $scope.myModel.replace(/“|”/gm, ''); // remove the quotes
      }

      $scope.addQuotes = function() {
        if ($scope.myModel == '') {
          $scope.myModel = ''; // dont add the quotes for an empty value
          return;
        }


        $scope.myModel = "“" + $scope.myModel + "”" // add the quotes again
      }
    }
  ])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="demoCtrl">
    <textarea ng-model="myModel" ng-focus='removeQuotes()' ng-blur='addQuotes()'></textarea>
  </div>

</div>

答案 1 :(得分:1)

您的要求非常有趣,可以分为两个主要功能:

1。在不影响模型值的情况下为视图值添加前缀和后缀

这是使用NgModelController实现的。我在ngModelController.$viewValue上创建了一个观察者,每当它发生变化时,如果它不包含前缀或后缀,我会添加这些值。

2。不允许用户干扰前缀或后缀

这有点棘手,但我找到a clever way on SO来获取和设置输入或textarea元素的插入位置。

这是一个有效的例子:

angular
  .module('myApp', [])
  .directive('beautifyText', function() {
    return {
      link: function(scope, iElement, iAttrs, ngModelController) {
        // Adds the prefix and suffix
        (function() {
          var prefix = iAttrs.beautifyTextWithPrefix;
          var suffix = iAttrs.beautifyTextWithSuffix;

          ngModelController.$parsers.push(function(value) {
            if (angular.isString(value)) {
              return value.replace(new RegExp('^' + prefix), '').replace(new RegExp(suffix + '$'), '');
            }

            return '';
          });

          scope.$watch(function() {
            return ngModelController.$viewValue;
          }, function(newValue) {
            if (angular.isString(newValue) && newValue.length > 0) {
              if (angular.isString(ngModelController.$modelValue) && ngModelController.$modelValue.length === 0 && newValue.length === 1) {
                ngModelController.$viewValue = '';
                ngModelController.$render();
                return;
              }

              if (!isBeautifiedWithPrefix(newValue)) {
                ngModelController.$viewValue = prefix + newValue;
              }

              if (!isBeautifiedWithSuffix(newValue)) {
                ngModelController.$viewValue = newValue + suffix;
              }

              ngModelController.$render();
            } else {
              ngModelController.$viewValue = '';
              ngModelController.$render();
            }
          });

          function isBeautifiedWithPrefix(value) {
            return value.match(new RegExp('^' + prefix)) !== null;
          }

          function isBeautifiedWithSuffix(value) {
            return value.match(new RegExp(suffix + '$')) !== null;
          }
        })();

        // Changes the caret position
        (function() {
          var element = iElement[0];

          // https://stackoverflow.com/questions/7745867/how-do-you-get-the-cursor-position-in-a-textarea#answer-7745998
          function getCursorPos() {
            if ("selectionStart" in element && document.activeElement == element) {
              return {
                start: element.selectionStart,
                end: element.selectionEnd
              };
            } else if (element.createTextRange) {
              var sel = document.selection.createRange();
              if (sel.parentElement() === element) {
                var rng = element.createTextRange();
                rng.moveToBookmark(sel.getBookmark());
                for (var len = 0; rng.compareEndPoints("EndToStart", rng) > 0; rng.moveEnd("character", -1)) {
                  len++;
                }
                rng.setEndPoint("StartToStart", element.createTextRange());
                for (var pos = {
                  start: 0,
                  end: len
                }; rng.compareEndPoints("EndToStart", rng) > 0; rng.moveEnd("character", -1)) {
                  pos.start++;
                  pos.end++;
                }
                return pos;
              }
            }
            return -1;
          }

          // https://stackoverflow.com/questions/7745867/how-do-you-get-the-cursor-position-in-a-textarea#answer-7745998
          function setCursorPos(start, end) {
            if (arguments.length < 2) {
              end = start;
            }

            if ("selectionStart" in element) {
              element.selectionStart = start;
              element.selectionEnd = end;
            } else if (element.createTextRange) {
              var rng = element.createTextRange();
              rng.moveStart("character", start);
              rng.collapse();
              rng.moveEnd("character", end - start);
              rng.select();
            }
          }

          iElement.bind('mousedown mouseup keydown keyup', function() {
            if (ngModelController.$viewValue.length > 0) {
              var caretPosition = getCursorPos();

              if (caretPosition.start === 0) {
                setCursorPos(1, caretPosition.end < 1 ? 1 : caretPosition.end);
              }

              if (caretPosition.end === ngModelController.$viewValue.length) {
                setCursorPos(caretPosition.start, ngModelController.$viewValue.length - 1);
              }
            }
          });
        })();
      },
      restrict: 'A',
      require: 'ngModel'
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>

<div ng-app="myApp">
  <textarea ng-model="myVariable" beautify-text beautify-text-with-prefix="“" beautify-text-with-suffix="”"></textarea>
  <p>myVariable: {{ myVariable }}</p>
</div>