2016-05-02 18 views
15

Tôi đang di chuyển cơ sở mã cũ của mình sang kiến ​​trúc thành phần mới được quảng cáo với AngularJS 1.5. Tôi đã gặp sự cố khi thực hiện việc này cho các biểu mẫu lớn hơn. Theo truyền thống, tôi sẽ đính kèm hình thức xác nhận như sau:Gửi biểu mẫu tới thành phần AngularJS để xác thực

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

Khi chuyển sang một kiến ​​trúc thành phần, tôi phải vượt qua một cách rõ ràng hình thức với thành phần:

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

Tôi muốn tránh gây ô nhiễm vm với mẫu của tôi. Có cách nào tốt hơn để đạt được kiến ​​trúc thành phần mong muốn cho các biểu mẫu không?

+0

Bạn không nên cần phải làm ô nhiễm mô hình tầm nhìn của bạn, tên mẫu là hoàn toàn tên cho bộ điều khiển hình thức, mà bạn có thể vượt qua để đầu vào của bạn thành phần. Mô hình khung nhìn của bạn chỉ cần phải lo lắng về các giá trị đầu vào. –

Trả lời

19

Update - thay đổi hình thức tên-hình thức tham chiếu, vì nó không phải là rõ ràng rằng chúng tôi đã đi qua các tài liệu tham khảo hình thức thực tế và không chỉ là tên của biểu mẫu. Điều này có thể được gọi là bất cứ điều gì bạn muốn, chỉ cần được rõ ràng về những gì nó thực sự là.

Khi nhận xét của Iain Reid cho biết, bạn không cần sử dụng vm cho việc này. Bạn chỉ cần đặt tên cho bất cứ điều gì hình thức mà bạn muốn và sau đó vượt qua tên đó để thành phần của bạn, vì vậy nó sẽ trông như thế này:

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

Đảm bảo rằng bạn viết "novalidate" trong hình thức của bạn để tắt kiểm chứng thực trình duyệt mặc định, nếu bạn muốn tự mình xử lý các xác nhận hợp lệ (do bạn sử dụng các thông điệp ng mà tôi nghĩ bạn làm).

Rồi từ đó, trên thành phần của tôi, tôi sẽ viết một cái gì đó như:

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

Và sau đó trong các mẫu đầu vào:

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

Một vài lưu ý thêm về các ràng buộc và làm thế nào để vượt qua và cập nhật mô hình:

  • '< ': có nghĩa là một cách ràng buộc, mà Angular nói để sử dụng cho tất cả các thành phần kể từ bây giờ. Để cập nhật giá trị và có hai cách ràng buộc, chúng tôi cần bao gồm chức năng "cập nhật".
  • onUpdate: '&' điều tôi đang nói ở đây là tôi sẽ chuyển một hàm để cập nhật mô hình (gọi lại cho các sự kiện thành phần).

Vì vậy, trong bộ điều khiển đầu vào Tôi sẽ viết một cái gì đó như:

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

Và, cuối cùng khi tôi sử dụng thành phần của tôi bên trong một hình thức:

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

Và bộ điều khiển của mẫu sẽ có chức năng:

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

Tài liệu chính thức: https://docs.angularjs.org/guide/component

Tôi hy vọng tất cả điều này giúp ai đó ngoài kia :-)

+1

Ví dụ tuyệt vời, nhưng có một điều có thể gây nhầm lẫn - trong ví dụ bạn đưa ra, bạn không ràng buộc tên biểu mẫu ("myForm") cho thành phần - bạn đang ràng buộc tham chiếu thực sự vào biểu mẫu. Tuy nhiên, nó hoạt động tuyệt vời, nhưng nó đã gây nhầm lẫn cho tôi một chút lúc đầu. –

+0

@SpencerSchneidenbach Tốt bắt. Đúng rồi – RGonzalez

Các vấn đề liên quan