2016-05-02 41 views
15

我將我的遺留代碼庫移至使用AngularJS 1.5提升的新組件體系結構中。我在爲較大的表單執行此操作時遇到了問題。傳統上,我會附上表單驗證如下:將表單傳遞給AngularJS組件進行驗證

<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> 

當過渡到一個組件架構,我不得不形式明確地傳遞到組件:

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

我想,以避免污染vm與我的形式。有沒有更好的方法來實現表單所需的組件架構?

+0

你不應該需要污染您的視圖模型,表格名稱純粹是爲了形成控制器,它你可以傳遞給你輸入姓名零件。您的視圖模型應該只需要擔心輸入值。 –

回答

19

更新 - 改變表單名稱形式引用,因爲它不是明確的,我們是通過實際的形式引用,而不是形式的只是名字。這可以稱爲任何你想要的,只是清楚它實際是什麼。

正如Iain Reid的評論所說,你不需要爲此使用vm。你只是名字你想要的形式,任何東西,然後通過這個名字給組件,因此它看起來像這樣:

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

確保您的表單中寫「的novalidate」禁用默認瀏覽器的驗證,如果你想要自己處理驗證(通過你使用ng-messages,我認爲你是這樣做的)。

然後從那裏,我的組件上我會寫這樣的:

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

然後在輸入模板:

<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說,從現在開始,所有 組件都使用該綁定。爲了更新該值並有兩種方式綁定,我們需要包含一個「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

一個很好的例子,但有一件事可能令人困惑 - 在你給出的例子中,你並沒有將表單名稱(「myForm」)綁定到組件上,而是將綁定到表單的實際引用。儘管如此,它的效果很好,但它起初讓我感到困惑。 –

+0

@SpencerSchneidenbach好的。那是對的 – RGonzalez