developer tip

AngularJS-서버 측 유효성 검사 및 클라이언트 측 양식

copycodes 2020. 12. 30. 08:19
반응형

AngularJS-서버 측 유효성 검사 및 클라이언트 측 양식


다음 작업을 수행하는 방법을 이해하려고합니다.

양식을 선언하는 데 허용되는 방법은 무엇입니까? 내 이해는 HTML로 양식을 선언하고 다음과 같이 ng-model 지시문을 추가한다는 것입니다.

ng-model="item.name"

서버로 보낼 내용. 항목 객체를 JSON으로 서버에 보내고 해석 할 수 있습니다. 그런 다음 객체에 대한 유효성 검사를 수행 할 수 있습니다. 실패하면 JSON 오류가 발생하고 정확히 무엇을 반환합니까? 이를 수행하는 허용 된 방법이 있습니까? 서버에서 클라이언트로 유효성 검사 오류를 좋은 방식으로 푸시하려면 어떻게해야합니까?

나는 정말 예제가 필요하지만 Angulars 문서는 이해하기가 매우 어렵습니다.

편집 : 내 질문을 잘못 표현한 것 같습니다.

클라이언트 측의 유효성을 검사하는 방법과 프라 미스 콜백으로 오류 / 성공을 처리하는 방법을 알고 있습니다. 내가 알고 싶은 것은 SERVER 측 오류 메시지를 클라이언트에 번들링하는 허용 된 방법입니다. 사용자 이름 및 비밀번호 가입 양식이 있다고 가정 해 보겠습니다. 서버에서 사용자 이름을 폴링하고 Angular를 사용하여 중복이 있는지 확인하고 싶지 않습니다. 사용자 이름을 서버에 보내고 같은 이름의 다른 계정이 없는지 확인한 다음 양식을 제출하고 싶습니다. 오류가 발생하면 어떻게 다시 보내야합니까?

다음과 같이 오류 필드가 추가 된 상태로 데이터를있는 그대로 (키 및 값) 서버에 푸시하는 것은 어떻습니까?

{
  ...data...

  "errors": [
    {
      "context": null,
      "message": "A detailed error message.",
      "exceptionName": null
    }
  ]
}

그런 다음 DOM에 바인딩합니다.


나는 또한 최근에 이런 종류의 것을 가지고 놀았고이 데모를 깨뜨렸다 . 나는 그것이 당신이 필요로하는 것을한다고 생각합니다.

사용하려는 특정 클라이언트 측 유효성 검사를 사용하여 정상적으로 양식을 설정하십시오.

<div ng-controller="MyCtrl">
    <form name="myForm" onsubmit="return false;">
        <div>
            <input type="text" placeholder="First name" name="firstName" ng-model="firstName" required="true" />
            <span ng-show="myForm.firstName.$dirty && myForm.firstName.$error.required">You must enter a value here</span>
            <span ng-show="myForm.firstName.$error.serverMessage">{{myForm.firstName.$error.serverMessage}}</span>
        </div>
        <div>
            <input type="text" placeholder="Last name" name="lastName" ng-model="lastName"/>
            <span ng-show="myForm.lastName.$error.serverMessage">{{myForm.lastName.$error.serverMessage}}</span>
        </div>
        <button ng-click="submit()">Submit</button>
    </form>
</div>

또한 serverMessage각 필드에 대해 추가했습니다 .

<span ng-show="myForm.firstName.$error.serverMessage">{{myForm.firstName.$error.serverMessage}}</span>

이것은 서버에서 돌아 오는 사용자 정의 가능한 메시지이며 다른 오류 메시지와 동일한 방식으로 작동합니다 (내가 말할 수있는 한).

컨트롤러는 다음과 같습니다.

function MyCtrl($scope, $parse) {
      var pretendThisIsOnTheServerAndCalledViaAjax = function(){
          var fieldState = {firstName: 'VALID', lastName: 'VALID'};
          var allowedNames = ['Bob', 'Jill', 'Murray', 'Sally'];

          if (allowedNames.indexOf($scope.firstName) == -1) fieldState.firstName = 'Allowed values are: ' + allowedNames.join(',');
          if ($scope.lastName == $scope.firstName) fieldState.lastName = 'Your last name must be different from your first name';

          return fieldState;
      };
      $scope.submit = function(){
          var serverResponse = pretendThisIsOnTheServerAndCalledViaAjax();

          for (var fieldName in serverResponse) {
              var message = serverResponse[fieldName];
              var serverMessage = $parse('myForm.'+fieldName+'.$error.serverMessage');

              if (message == 'VALID') {
                  $scope.myForm.$setValidity(fieldName, true, $scope.myForm);
                  serverMessage.assign($scope, undefined);
              }
              else {
                  $scope.myForm.$setValidity(fieldName, false, $scope.myForm);
                  serverMessage.assign($scope, serverResponse[fieldName]);
              }
          }
      };
}

나는 pretendThisIsOnTheServerAndCalledViaAjax당신이 ajax 호출로 대체 할 수 있는 서버를 호출하는 척하고 있습니다. 요점은 각 필드에 대한 유효성 검사 상태를 반환한다는 것입니다. 이 간단한 경우 값 VALID사용하여 필드가 유효 함을 나타내며 다른 값은 오류 메시지로 처리됩니다. 좀 더 정교한 것을 원할 수도 있습니다!

서버에서 유효성 검사 상태를 얻은 후에는 양식에서 상태를 업데이트하기 만하면됩니다.

범위에서 양식에 액세스 할 수 있습니다.이 경우 양식이 호출 myForm되므로 $ scope.myForm이 양식을 가져옵니다. ( 어떻게 작동하는지 읽고 싶다면 폼 컨트롤러의 소스 가 여기 에 있습니다).

그런 다음 해당 필드가 유효한지 여부를 양식에 알려야합니다.

$scope.myForm.$setValidity(fieldName, true, $scope.myForm);

또는

$scope.myForm.$setValidity(fieldName, false, $scope.myForm);

오류 메시지도 설정해야합니다. 먼저 $ parse를 사용하여 필드에 대한 접근자를 가져옵니다. 그런 다음 서버에서 값을 지정하십시오.

var serverMessage = $parse('myForm.'+fieldName+'.$error.serverMessage');
serverMessage.assign($scope, serverResponse[fieldName]);

도움이되는 희망


codetunes blog에 설명 된 Derek과 유사한 솔루션이 있습니다. TL; DR :

  • Derek의 솔루션과 유사한 방식으로 오류를 표시합니다.

    <span ng-show="myForm.fieldName.$error.server">{{errors.fieldName}}</span>
    

  • 사용자가 입력을 변경할 때 오류를 정리하는 지시문을 추가합니다.

    <input type="text" name="fieldName" ng-model="model.fieldName" server-error />
    
    angular.module('app').directive 'serverError', ->
      {
        restrict: 'A'
        require: '?ngModel'
        link: (scope, element, attrs, ctrl) ->
          element.on 'change', ->
            scope.$apply ->
              ctrl.$setValidity('server', true)
      }
    
  • 오류 메시지를 범위에 전달하고 양식에 오류가 있음을 알려 오류를 처리합니다.

    errorCallback = (result) ->
      # server will return something like:
      # { errors: { name: ["Must be unique"] } }
      angular.forEach result.data.errors, (errors, field) ->
        # tell the form that field is invalid
        $scope.form[field].$setValidity('server', false)
        # keep the error messages from the server
        $scope.errors[field] = errors.join(', ') 
    

유용하길 바랍니다 :)


글쎄, Derek Ekins가 준 답변은 작업하기에 매우 좋습니다. 그러나 : 제출 버튼을 비활성화하면 ng-disabled="myForm.$invalid"-버튼은 서버 기반 오류 상태가 변경되지 않는 것처럼 보이기 때문에 자동으로 활성화 상태로 돌아 가지 않습니다. 유효한 입력을 준수하기 위해 양식의 모든 필드를 다시 편집하더라도 (클라이언트 측 유효성 검사를 기반으로) 불가능합니다.


기본적으로 양식은 정상적으로 제출됩니다. 양식의 각 필드에 이름 속성을 제공하지 않으면 올바른 데이터가 제출되지 않습니다. 할 수있는 일은 제출하기 전에 양식을 캡처하고 해당 데이터를 ajax를 통해 직접 제출하는 것입니다.

<form ng-submit="onSubmit(); return false">

그리고 당신의 $scope.onSubmit()기능에서 :

$scope.onSubmit = function() {
  var data = {
    'name' : $scope.item.name
  };
  $http.post(url, data)
    .success(function() {
    })
    .failure(function() {

    });
};

필수 속성을 설정하여 데이터의 유효성을 검사 할 수도 있습니다.


ngResource를 선택하면 다음과 같습니다.

var Item = $resource('/items/');
$scope.item = new Item();
$scope.submit = function(){
  $scope.item.$save(
    function(data) {
        //Yahooooo :)
    }, function(response) {
        //oh noooo :(
        //I'm not sure, but your custom json Response should be stick in response.data, just inspect the response object 
    }
  );
};

가장 중요한 것은 HTTP-Response 코드가 실패 콜백에 들어가려면 4xx 여야한다는 것입니다.


2014 년 7 월부터 AngularJS 1.3에는 새로운 양식 유효성 검사 기능이 추가되었습니다. 여기에는 ngMessages 및 asyncValidators가 포함되므로 양식을 제출하기 전에 필드별로 서버 측 유효성 검사를 실행할 수 있습니다.

Angular 1.3 양식 유효성 검사 자습서 :

참조 :


몇 가지 프로젝트에서 필요했기 때문에 지시문을 만들었습니다. 드디어 드롭 인 솔루션을 원하는 사람을 위해 GitHub에 게시했습니다.

https://github.com/webadvanced/ng-remote-validate

풍모:

  • 모든 텍스트 또는 비밀번호 입력의 Ajax 유효성 검사를위한 드롭 인 솔루션

  • Angulars 빌드 유효성 검사와 함께 작동하며 formName.inputName. $ error.ngRemoteValidate에서 cab에 액세스 할 수 있습니다.

  • 서버 요청 (기본값 400ms)을 제한하며 다음으로 설정할 수 있습니다. ng-remote-throttle="550"

  • ng-remote-method="GET"사용자가 현재 암호와 새 암호를 입력해야하는 암호 변경 양식에 대한 예제 사용 과 함께 HTTP 메서드 정의 (기본 POST)를 허용 합니다. :

    비밀번호 변경

    현재 필수 잘못된 현재 암호입니다. 현재 계정 비밀번호를 입력하세요.
    <label for="newPassword">New</label>
    <input type="password"
           name="newPassword"
           placeholder="New password"
           ng-model="password.new"
           required>
    
    <label for="confirmPassword">Confirm</label>
    <input ng-disabled=""
           type="password"
           name="confirmPassword"
           placeholder="Confirm password"
           ng-model="password.confirm"
           ng-match="password.new"
           required>
    <span ng-show="changePasswordForm.confirmPassword.$error.match">
        New and confirm do not match
    </span>
    
    <div>
        <button type="submit" 
                ng-disabled="changePasswordForm.$invalid" 
                ng-click="changePassword(password.new, changePasswordForm);reset();">
            Change password
        </button>
    </div>
    

변형으로

// ES6 form controller class

class FormCtrl {
 constructor($scope, SomeApiService) {
   this.$scope = $scope;
   this.someApiService = SomeApiService;
   this.formData = {};
 }

 submit(form) {
   if (form.$valid) {
     this.someApiService
         .save(this.formData)
         .then(() => {
           // handle success

           // reset form
           form.$setPristine();
           form.$setUntouched();

           // clear data
           this.formData = {};
         })
         .catch((result) => {
           // handle error
           if (result.status === 400) {
             this.handleServerValidationErrors(form, result.data && result.data.errors)
           } else {// TODO: handle other errors}
         })
   }
 }

 handleServerValidationErrors(form, errors) {
  // form field to model map
  // add fields with input name different from name in model
  // example: <input type="text" name="bCategory" ng-model="user.categoryId"/>
  var map = {
    categoryId: 'bCategory',
    // other
  };

  if (errors && errors.length) {
    // handle form fields errors separately
    angular.forEach(errors, (error) => {
      let formFieldName = map[error.field] || error.field;
      let formField = form[formFieldName];
      let formFieldWatcher;

      if (formField) {
        // tell the form that field is invalid
        formField.$setValidity('server', false);

        // waits for any changes on the input
        // and when they happen it invalidates the server error.
        formFieldWatcher = this.$scope.$watch(() => formField.$viewValue, (newValue, oldValue) => {
          if (newValue === oldValue) {
            return;
          }

          // clean up the server error
          formField.$setValidity('server', true);

          // clean up form field watcher
          if (formFieldWatcher) {
            formFieldWatcher();
            formFieldWatcher = null;
          }
        });
      }
    });

  } else {
    // TODO: handle form validation
    alert('Invalid form data');
  }
}

참조 URL : https://stackoverflow.com/questions/16168355/angularjs-server-side-validation-and-client-side-forms

반응형