programing

AngularJS - 서버측 검증 및 클라이언트측 폼

newsource 2023. 3. 31. 22:26

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]);
              }
          }
      };
}

는 버를 in in에 있는 을 하고 .pretendThisIsOnTheServerAndCalledViaAjax아약스중요한 것은 각 필드의 검증 상태를 반환하는 것입니다., 저는 이 값을 .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]);

코데튠즈 블로그에 나와 있는 데릭과 비슷한 해결책을 찾았어요TL;DR:

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

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

  • add 디렉티브를 사용하면 사용자가 입력을 변경할 때 오류가 해결됩니다.

    <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(', ') 
    

도움이 되었으면 합니다:)

에킨즈입니다. 송신 을 「」로 ,[송신]버튼을 비활성화하면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 와 asyncValidator 가 포함됩니다.이것에 의해, 폼을 송신하기 전에, 필드 마다 서버측의 검증을 실행할 수 있게 됩니다.

Angular 1.3 검증 튜토리얼:

참고 자료:

몇 가지 프로젝트에서 이것이 필요했기 때문에 지시문을 작성했습니다.드디어 드롭인 솔루션을 원하는 사람을 위해 GitHub에 올렸습니다.

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

특징:

  • 텍스트 또는 비밀번호 입력에 대한 Ajax 검증을 위한 솔루션 폐기

  • Angulars와 연동하여 검증하고 formName.inputName에서 cab에 액세스합니다.$error.ngRemoteValidate

  • 서버 요청을 조절합니다(기본값 400ms).ng-remote-throttle="550"

  • HTTP 메서드의 정의(디폴트 POST)를 허가합니다.ng-remote-method="GET"사용자가 현재 비밀번호와 새 비밀번호를 입력해야 하는 비밀번호 변경 폼의 사용 예:

    비밀번호 변경

    Current Required 현재 비밀번호가 잘못되었습니다.현재 계정 암호를 입력하십시오.
    <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');
  }
}

질문은 서버에서 클라이언트로 오류를 전달하는 것으로 알고 있습니다.나는 잘 확립된 관행이 있는지 잘 모르겠다.가능한 접근법에 대해 설명하겠습니다.

<form name="someForm" ng-submit="submit()" ng-controller="c1" novalidate>
    <input name="someField" type="text" ng-model="data.someField" required>
    <div ng-show="someForm.$submitted || someForm.someField.$touched">
        <div ng-show="someForm.someField.$error.required" class="error">required</div>
        <div ng-show="someForm.someField.$error.someError" class="error">some error</div>
    </div>
    <input type="submit">
</form>

서버가 다음 종류의 개체를 반환한다고 가정합니다.

{errors: {
    someField: ['someError'],
}}

그런 다음 다음과 같은 방법으로 오류를 UI에 전달할 수 있습니다.

Object.keys(resp.errors).forEach(i => {
    resp.errors[i].forEach(c => {
        $scope.someForm[i].$setValidity(c, false);
        $scope.someForm[i].$validators.someErrorResetter
            = () => $scope.someForm[i].$setValidity(c, true);
    });
});

각 필드를 비활성화하고 검증자(실제로 검증자가 아님)를 추가합니다.변경 후 검증자가 호출되므로 에러 상태를 리셋합니다.

여기서 실험할 수 있습니다.그리고 관련 기사도 확인해 보세요.

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