57

次のことを行う方法を理解しようとしています。

フォームを宣言するために受け入れられている方法は何ですか。私の理解では、HTML でフォームを宣言し、次のように ng-model ディレクティブを追加するだけです。

ng-model="item.name"

サーバーに送信するもの。item オブジェクトを JSON としてサーバーに送信し、解釈するだけです。次に、オブジェクトの検証を実行できます。失敗した場合は、JSON エラーをスローし、正確には何を送り返しますか? これを行うための受け入れられた方法はありますか?サーバーからクライアントに検証エラーを適切にプッシュするにはどうすればよいですか?

本当に例が必要ですが、Angulars のドキュメントは理解するのがかなり難しいです。

編集:質問の言い回しが不十分だったようです。

クライアント側を検証する方法と、エラー/成功を約束のコールバックとして処理する方法を知っています。私が知りたいのは、サーバー側のエラーメッセージをクライアントにバンドルする受け入れられた方法です。ユーザー名とパスワードの登録フォームがあるとします。サーバーにユーザー名をポーリングしてから、Angular を使用して重複が存在することを確認したくありません。ユーザー名をサーバーに送信し、同じ名前のアカウントが他に存在しないことを確認してから、フォームを送信します。エラーが発生した場合、どうすれば返送できますか?

次のようにエラーフィールドを追加して、データをそのまま(キーと値)サーバーにプッシュするのはどうですか。

{
  ...data...

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

次に、DOM にバインドします。

4

9 に答える 9

3

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 応答コードが 4xx でなければならないということです。

于 2013-04-23T14:40:41.183 に答える
3

デフォルトでは、フォームは正常に送信されます。フォームの各フィールドに name プロパティを指定しないと、正しいデータが送信されません。できることは、フォームを送信する前にキャプチャし、そのデータを 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() {

    });
};

必須属性を設定して、データを検証することもできます。

于 2013-04-23T12:26:18.690 に答える
2

いくつかのプロジェクトでこれが必要だったので、ディレクティブを作成しました。最後に、ドロップイン ソリューションが必要な人のために、GitHub にアップするのに時間がかかりました。

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

特徴:

  • テキストまたはパスワード入力の Ajax 検証のためのドロップイン ソリューション

  • Angulars ビルドの検証で動作し、formName.inputName.$error.ngRemoteValidate でアクセスできます。

  • サーバー要求を抑制し (デフォルトは 400 ミリ秒)、次のように設定できます。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>
    
于 2014-04-24T23:11:33.733 に答える
1

バリアントとして

// 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');
  }
}
于 2015-06-18T10:59:08.110 に答える
0

私が理解しているように、質問はサーバーからクライアントにエラーを渡すことです。確立された慣行があるかどうかはわかりません。そこで、考えられるアプローチについて説明します。

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

各フィールドを無効にし、バリデーターを追加します (これは実際にはバリデーターではありません)。バリデーターはすべての変更後に呼び出されるため、エラーステータスをリセットしましょう。

ここで試すことができます。もご覧くださいngMessages。そして、いくつかの関連 記事.

于 2021-11-27T15:47:40.543 に答える