0

私は私の問題を説明するplnkrを作成しました:Link to plnkr角度指令変更ngmodel値未定義の休憩に検証

問題の説明: 私は番号フィールドを持って、モデルに書き込まれ、そこから値を。まず、最初の入力と同様にこの機能を実装しました。この実装での問題は、私は入力何かして削除した場合、私は次のモデルがあるということです。

{"secondNumber":64} 

:私にとって

{"firstNumber":null,"secondNumber":64} 

を残念ながら、この表現は受け入れられない、私は次のような結果が必要そのために、私はその指示を受けて、2番目のフィールドを実装しました。今すぐ正しい出力が得られますが、値を削除するとフォームが無効になります。

また、3番目と4番目の入力を追加して、ディレクティブが必要な検証をも破っていることを実証しました。

だから、質問は次のとおりです。 どうやってモデル

{"firstNumber":null,"secondNumber":64} 

しかし

{"secondNumber":64} 

を持っていない入力フィールドを向上させることができ、角の形の検証メカニズムを壊しません。

参考

: I次のHTMLを持っている:

<body ng-controller="MainCtrl as vm"> 
<h1>Validating input inside ng-repeat with Angular 1.3</h1> 

<form name="vm.myForm" novalidate> 
    <input type="number" ng-model="vm.fields.firstNumber" name="firstNumber"> 
    <input type="number" ng-model="vm.fields.secondNumber" name="secondNumber" null-to-undefined> 
    <br> 
    <input type="number" ng-model="vm.fields.thirdNumber" name="thirdNumber" ng-required = "true"> 
    <input type="number" ng-model="vm.fields.fourthNumber" name="fourthNumber" null-to-undefined ng-required="true"> 
</form> 
</body> 

そして、次のコントローラとのディレクティブコード:

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope) { 
    var vm = this; 

    vm.fields = {}; 
    vm.fields.firstNumber = 12; 
    vm.fields.secondNumber = 24; 
    vm.fields.thirdNumber = 64; 
    vm.fields.fourthNumber = 128; 

}); 

app.directive('nullToUndefined', function($timeout) { 
    return { 
    restrict: 'A', 
    require: 'ngModel', 
    link: function(scope, elem, attrs, ctrl) { 
     ctrl.$parsers.push(function(viewValue, modelValue) { 
     if (viewValue === null) { 
      $timeout(function() { 
      //ctrl.$setValidity('number', true); 
      }); 
      return undefined; 
     } 
     return viewValue; 
     }); 
    } 
    }; 
}); 

P.S.私はメインプロジェクトから問題を再現するためにできるだけコードをカットしました。私はどんな解決策もありがとうと思いますが、誰かが解決策を提案できれば非常に涼しいでしょう: 1.良い性能を示します 2.角をなして動作します。

答えて

1

おそらく、ディレクティブを書く代わりに、他の解決策に焦点を合わせるべきです。

あなたは小道具(firstNumber、secondNumber、...)を持つオブジェクトを持っています。

プロパティを確認する必要があります。角度(null?は正しい番号ですか?)です。

次に、モデルの突然変異なしにオブジェクトの小道具をヌル値でフィルタリングする必要があります。入力がモデルプロパティにバインドされています。プロパティを破棄すると、Angularは検証および失敗できません。

我々はそれを行うことができます。

  • のすべてのキーを選択します。フィールド
  • 反復は、我々はすべての非nullキー
  • は「」
const a = { 
    fields: { 
    a: 1, 
    b: 2, 
    c: null, 
    }, 
}; 

// After form validation 
const newA = Object 
    .keys(a.fields) 
    .filter(k => a.fields[k] !== null) 
    .reduce(
    (accumulator, k) => 
     Object.assign(
     accumulator, 
     { 
      fields: Object.assign(accumulator.fields, { [k]: a.fields[k] }) 
     } 
    ), 
    { fields: {} } 
); 

の変異なしに、新しいオブジェクトにnull以外のキーを減らして得たすべてのキー、フィルタ

  • そして、定義されていない+ nullをフィルタリングする必要がある場合は、フィルタをほとんどチェックしないでください:

    .filter(k => a.fields[k] != null) 
    

    編集:fi xコード。

  • +0

    お返事ありがとうございます。残念ながら、私はこのコードを試して、エラーが発生しました 'prev is undefined'です。しかし、私はnullを削除し、私のオブジェクトから値をundefiend別のコードを確認しました。 – CodeMonkey

    +0

    それは働いた。 しかし、私の場合、ディレクティブのオプションが示唆されているように働くならば、それを適用する方が良いでしょう。そこで、上記の解決策を一時的なものとして適用しました。 – CodeMonkey

    +1

    私は "prev is undefined"というエラーを修正しました。 –