2016-05-02 4 views
15

私は、従来のコードベースをAngularJS 1.5で宣伝された新しいコンポーネントアーキテクチャに移行します。より大きなフォームでこれを行うときに問題が発生しました。フォームをAngularJSコンポーネントに渡して検証します

<form name="vm.myForm"> 
    <my-awesome-input-component model="vm.input1" form="vm.myForm"><my-awesome-input-component> 
    <!-- many more inputs --> 
</form> 

は私がvm汚染を回避したいと思います:

<form name="myForm"> 
    <input type="text" name="input1" ng-model="vm.input1" required /> 
    <div ng-messages="myForm.input1.$error"> 
    <div ng-message="required">Please fill out this field.</div> 
    </div> 
    <!-- many more inputs --> 
</form> 

コンポーネントアーキテクチャへの移行、私は明示的にコンポーネントにフォームを渡す必要があり、次のように伝統的に、私は、フォームの検証を添付します私のフォームでフォームに必要なコンポーネントアーキテクチャを実現するためのより良い方法はありますか?

+0

:-)そこに誰かに役立ちます願って、フォーム名は、純粋に、あなたの入力に渡すことができますフォームコントローラ、の名前です成分。あなたのビューモデルは、入力値を心配する必要があります。 –

答えて

19

アップデート - 我々は、フォームの名前だけで、実際のフォームの参照を渡すとされていないことを明示しなかったことから、にフォーム参照フォーム名を変更しました。これは、あなたが望むものであれば、実際にはっきりしているものと呼ぶことができます。

Iain Reidのコメントによると、これにはVMを使用する必要はありません。あなたはちょうどあなたが望むフォームには任意の名前を付けると、あなたのコンポーネントにその名前を渡すので、次のようになります。あなたがいる場合、デフォルトのブラウザの検証を無効にするには、フォームで「NOVALIDATE」を書き込むことを確認すること

<form name="myForm" ng-submit="ctrl.someFunction()" novalidate> 
    <my-input form-reference="myForm"></my-input> 
    <button type="submit">Some button</button> 
</form> 

あなた自身の検証を処理したい(これはあなたが思っているメッセージの使用によって)。

<input type="text" name="myInput" ng-model="$ctrl.myInputModel" ng-change="$ctrl.update($ctrl.myInputModel)" required /> 
<div ng-messages="$ctrl.formReference.myInput.$error"> 
    <div ng-message="required">Please fill out this field.</div> 
</div> 

いくつかの余分なバインディング上の注意事項と方法を渡すために:入力テンプレートで、その後

angular.module("myApp") 
    .component("myInput",{ 
    templateUrl:'path/to/template.html' 
    bindings:{ 
     formReference:'<', 
     myInputModel:'<', 
     onUpdate:'&' 
    }, 
    controller: MyInputController 
    } 

そして:次に

そこから、私のコンポーネントに私のような何かを書くだろう更新モデル:

  • '< ':これ以降のすべての コンポーネントにAngularが使用する一方向バインディングを意味します。値を更新し、2通りの方法でバインドするには、 "onUpdate"関数をインクルードする必要があります。
  • onUpdate: '&'ここで私が言っているのは、 関数を渡してモデル(コンポーネントイベントのコールバック)を更新することです。私は、フォーム内の私のコンポーネントを使用する場合、最後に、

    function MyInputController(){ 
        var ctrl = this; 
        ctrl.update = function(value){ 
         ctrl.onUpdate({value: value}); 
        }; 
    } 
    

    そして:

ので、入力コントローラに私のような何かを書くだろう

<form name="myForm" ng-submit="ctrl.someFunction()" novalidate> 
    <my-input form-reference="myForm" my-input-model="ctrl.anyModelIWant" on-update="ctrl.updateMyInput(value)"></my-input> 
    <button type="submit">Some button</button> 
</form> 

、フォームのコントローラだろう機能を有する:

... 
ctrl.updateMyInput = function(value){ 
    ctrl.anyModelIWant = value; 
} 
... 

公式ドキュメント:https://docs.angularjs.org/guide/component

私はこれのすべてはあなたのビューモデルを汚染する必要はありません

+1

しかし、混乱するかもしれない1つの例 - あなたが与えた例では、フォーム名( "myForm")をコンポーネントにバインドしていません。フォームへの実際の参照をバインドしています。それでも素晴らしいことですが、最初はちょっと混乱しました。 –

+0

@SpencerSchneidenbach良いキャッチ。それは正しいです – RGonzalez

関連する問題