web-dev-qa-db-ja.com

AngularJSフォームとnull /空の値

やや動的なAngularJSフォームを使用しています。つまり、入力フィールドの行などを追加できます。つまり、$scope.formData空のオブジェクトから始めて、静的および動的なHTMLフォーム要素の両方にバインドされているすべてのプロパティをカプセル化しました。

AngularJSコードは次のとおりです。

(function() {
    var formApp = angular.module("formApp", []);
    formApp.controller("FormCtrl", function ($scope, $timeout) {
        $scope.formData = {};
        $scope.formData.subscribers = [
            { name: null, email: null }
        ];
        $scope.addSubscriber = function() {
            $scope.formData.subscribers.Push({ name: null, email: null });
        };
    });
})();

AngularJSフォームのHTML:

<body data-ng-app="formApp">
    <div data-ng-controller="FormCtrl">
        <p>
            Name of Topic: <input type="text" data-ng-model="formData.title" placeholder="enter a title" />
        </p>
        Subscribers:
        <button data-ng-click="addSubscriber()">Add subscriber</button>
        <table>
            <tr>
                <th>Name</th>
                <th>Email</th>
            </tr>
            <tr data-ng-repeat="subscriber in formData.subscribers">
                <td><input type="text" data-ng-model="subscriber.name" placeholder="enter name" /></td>
                <td><input type="text" data-ng-model="subscriber.email" placeholder="enter email" /></td>
            </tr>
        </table>
        <hr style="margin:1em 0;" />
        <p>
            <em>Debug info</em>: {{ formData }}
        </p>
    </div>
</body>

最後のDebug infoセクションに注意してください。このセクションには、$scope.formDataオブジェクトとその内容が表示されます。このフォームの実装方法にいくつか問題があります。

  • ページが最初に読み込まれたとき、formData.title$scopeプロパティはありませんが、タイトル入力テキストフィールドにバインドされているため、値の入力を開始すると、titleプロパティ$scopeに追加されます。ただし、入力テキストフィールドの値を削除しても、formData.titleプロパティは空の文字列として$scopeにまだ存在します。私はこれで大丈夫だと思いますが、フォームを送信するときに本当に空またはnull値をクリーンアップしたいと思います。簡単に実行できる場合はクライアント側で実行したいので、サーバー側のコードで何もクリーンアップする必要はありません。
  • 動的Subscribersセクションを使用すると、必要なだけ行を追加し続けることができますが、最終的に、すべての空のsubscriberクライアント側のオブジェクト。

AngularJSには、$scope POSTなど、さらに処理する前に$httpのnull /空の値を検出して消去するオプションがありますか?

この例では jsFiddle を設定しました。

8
Web User

単に ngModelController $ parsersを使用し、デフォルトのHTML入力要素を上書きします。

この実装により、常にモデル値を制御できます。したがって、あなたの場合、ビューの値が空の文字列であるときはいつでもモデルをnullに設定できます。

var inputDefinition = function () {
return {
  restrict: 'E',
  require: '?ngModel',
  link: function (scope, element, attr, ngModel) {
    if (ngModel) {
      var convertToModel = function (value) {
        return value === '' ? null : value;
      };
      ngModel.$parsers.Push(convertToModel);
    }
  }
};
/**
* Overwrite default input element.
*/
formApp.directive('input', inputDefinition);

更新されたJSFiddleは次のとおりです。 https://jsfiddle.net/9sjra07q/

4
Tome Pejoski
function replacer(key, value) {
    if (value == "" || value == null) {
       return undefined;
    }
  return value;
}

var foo = {foundation: "", model: {year: 2015, price:null}, week: 45, transport: "car", month: 7};
foo = JSON.stringify(foo, replacer);
foo =JSON.parse(foo);
console.log(foo);
2
Raj

パフォーマンス上の理由から、ウォッチャーの使用は避けています。そうは言っても、これは実際にはAngularの質問ではなく、JavaScriptの質問です。データがサービスに渡されるタイミングを完全に制御できるので、データ構造が非常に浅いため、これはかなり簡単です。

https://jsfiddle.net/1ua6oj5e/9/

(function() {
    var formApp = angular.module("formApp", []);
    formApp.controller("FormCtrl", function ($scope, $timeout) {

        // Remove junkiness
        var _remove = function remove(item) {
            if ($scope.formData.title === undefined || $scope.formData.title === '') {
                delete $scope.formData.title;
            }
        };


        $scope.formData = {};
        $scope.formData.subscribers = [
            { name: null, email: null }
        ];
        $scope.addSubscriber = function() {
            $scope.formData.subscribers.Push({ name: null, email: null });
        };

        // Submit to test functionality
        $scope.submit = function() {

            // Remove title if empty
            _remove($scope.formData.title);

            /* Remove name and email if empty.
             * If your list of fields starts to get large you could always
             * just nest another iterator to clean things up.                 
             */

            angular.forEach($scope.formData.subscribers, function(sub) {
                _remove(sub.name);
                _remove(sub.email);
            });

        };
    });
})();
2
Scott Sword

FormDataにWatcherを追加しました。

$scope.$watch('formData',function(n,o){
      if(typeof $scope.formData.title !== 'undefined' && $scope.formData.title === "" ){
        delete $scope.formData.title;
      }
},true);

更新されたフィドル: https://jsfiddle.net/1ua6oj5e/6/

すべての動的フィールドでangular form validationを使用すると、次のように表示されます: https://docs.angularjs.org/guide/forms