programing

ng-max-length가 내 모델을 나사로 고정합니다.

testmans 2023. 3. 21. 21:46
반응형

ng-max-length가 내 모델을 나사로 고정합니다.

검증과 함께 "so many chars"가 남아 있는 단순한 텍스트 영역을 작성하려고 합니다.ng-max length를 사용하여 폼을 검증하면 길이가 최대 길이에 도달하는 즉시 문자 수가 리셋됩니다.여기 문제가 있어요 해결 방법이 있나요?

  <body ng-controller="MainCtrl">
    <div ng-form="noteForm">
      <textarea ng-maxlength="15" ng-model="result"></textarea>
      <p>{{15 - result.length}} chars remaining</p>
      <button ng-disabled="!noteForm.$valid">Submit</button>
    </div>
  </body>

텍스트 영역이 15자를 초과하면result된다undefined--그렇게 해서ng-min/maxlength지시는 효과가 있습니다.직접 지시문을 작성하셔야 할 것 같습니다.다음은 15자 이후의 입력을 차단하는 지시문입니다.

<textarea my-maxlength="15" ng-model="result"></textarea>
app.directive('myMaxlength', function() {
  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ngModelCtrl) {
      var maxlength = Number(attrs.myMaxlength);
      function fromUser(text) {
          if (text.length > maxlength) {
            var transformedInput = text.substring(0, maxlength);
            ngModelCtrl.$setViewValue(transformedInput);
            ngModelCtrl.$render();
            return transformedInput;
          } 
          return text;
      }
      ngModelCtrl.$parsers.push(fromUser);
    }
  }; 
});

fiddle


업데이트: 15자를 초과하여 송신 버튼을 비활성화하려면 , 다음의 순서에 따릅니다.

link: function (scope, element, attrs, ngModelCtrl) {
  var maxlength = Number(attrs.myMaxlength);
  function fromUser(text) {
      ngModelCtrl.$setValidity('unique', text.length <= maxlength);
      return text;
  }
  ngModelCtrl.$parsers.push(fromUser);
}

fiddle

또는 표준 html을 추가할 수도 있습니다.maxlength옆에 있는 것으로 간주ng-maxlength.

<form name="myForm">
    <textarea name="myTextarea" ng-maxlength="15" maxlength="15" ng-model="result"></textarea>
    <span class="error" ng-show="myForm.myTextarea.$error.maxlength">
         Reached limit!
     </span>
</form>

이렇게 하면 다음과 같이 "15"자로 끊어집니다.maxlength항상 그래왔으며, 추가적으로ng-maxlength그럼 제한에 도달했을 때 커스텀메시지를 표시할 수 있습니다.

클릭해서 플런커 예시

이름 속성을 텍스트 영역에 추가하면 값이 포함된 새 속성이 양식 범위에 생성되며, 이를 사용하여 문자 카운터의 길이를 가져올 수 있습니다.

<body ng-controller="MainCtrl">
  <div ng-form="noteForm">
    <textarea ng-maxlength="15" name="noteItem" ng-model="result"></textarea>
    <p>{{15 - noteForm.noteItem.$viewValue.length}} chars remaining</p>
    <button ng-disabled="!noteForm.$valid">Submit</button>
  </div>
</body>

PLNKR 업데이트

문서에서 설명한 바와 같이 $validate 함수는 유효성이 무효로 변경되면 모델을 정의되지 않음으로 설정합니다.

하지만, 이 동작을 예방할 수 있는 방법은allowInvalid: trueng-model-model-model-model

따라서 코드를 다음과 같이 수정하십시오.

<body ng-controller="MainCtrl">
    <div ng-form="noteForm">
        <textarea ng-maxlength="15" ng-model="result" 
            ng-model-options="{ allowInvalid: true }"></textarea>
        <p>{{15 - result.length}} chars remaining</p>
        <button ng-disabled="!noteForm.$valid">Submit</button>
    </div>
</body>

이건 앵귤러에 버그로 기록해야 할 것 같아요.모델을 클리어하면 안 됩니다.드롭다운 선택 항목을 텍스트 상자에 링크하는 지시문이 있으며, 최대 길이를 초과하는 단어를 삽입하면 모델과 텍스트 상자가 지워집니다.검증자는 모델이 유효하지 않다고 생각될 때 모델을 삭제하지 않아야 합니다.

또 다른 방법은 ng-max-length 검증기와 동일한 동작을 유지하되 추가 속성 'actual-length'를 통해 길이를 피드백하는 것입니다.

app.directive('newMaxlength', function () {
        return {
            require: 'ngModel',
            scope: {
                maxlength: '=newMaxlength',
                actualLength: '='
            },
            link: function (scope, elem, attr, ngModelCtrl) {

                function validate(ctrl, validatorName, validity, value) {
                    ctrl.$setValidity(validatorName, validity);
                    return validity ? value : undefined;
                }

                var maxlength = parseInt(scope.maxlength, 10);
                var maxLengthValidator = function (value) {
                    scope.actualLength = value ? value.length : 0;
                    return validate(ngModelCtrl, 'maxlength', ngModelCtrl.$isEmpty(value) || value.length <= maxlength, value);
                };

                ngModelCtrl.$parsers.push(maxLengthValidator);
                ngModelCtrl.$formatters.push(maxLengthValidator);
            }
        };
    });

추가 속성을 가진 요소를 다음에 나타냅니다.

<textarea name="myTextarea" new-maxlength="100" actual-length="actualLength" ng-model="text"></textarea>

더 나은 해결책이 있습니다.ng-maxlength가 존재하는 경우 maxlength를 설정하는 것입니다.

이렇게 하면 각도 검증 + 텍스트 잘라내기 두 가지 기능을 동시에 얻을 수 있습니다.

.directive("textarea", function () {
    return {
        restrict: "E",
        link: function (scope, elem, attrs) {
            if (angular.isDefined(attrs["ngMaxlength"])) {
                attrs.$set("maxlength", attrs["ngMaxlength"]);
            }
        }
    };
})

언급URL : https://stackoverflow.com/questions/17075969/ng-maxlength-screws-up-my-model

반응형