Tôi có thể truy cập một biểu mẫu trong bộ điều khiển không?


152

Tôi hiện đang sử dụng như sau.

$scope.$$childHead.customerForm[firstName], vậy nên:

<form name="customerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" 
         tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>

Nhưng điều này chỉ hoạt động trong Chrome. Bây giờ tôi đã thử như sau:

$scope.editCustomerForm[firstName], vậy nên:

<form name="customerForm" ng-model="editCustomerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>

Mà không làm việc. Lưu ý biểu mẫu của tôi nằm trong Tab Foundation. Làm thế nào tôi có thể truy cập firstName?

EDIT : Có vẻ như formkhông được thêm vào scopekhi nó nằm trong Tab Foundation.

Bất cứ ai cũng có một giải pháp cho điều này?

Câu trả lời:


210

Mặc dù được nhắc đến trong các bình luận khác, tôi nghĩ tôi sẽ đánh vần nó một chút cho những người sử dụng cú pháp "Trình điều khiển dưới dạng":

<div ng-controller="MyController as ctrl">

<form name="ctrl.myForm">
    ...inputs
    Dirty? {{ctrl.myForm.$dirty}}

    <button ng-click="ctrl.saveChanges()">Save</button>
</form>

</div>

Sau đó, bạn có thể truy cập FormContoder trong mã của mình như:

function MyController () {
    var vm = this;
    vm.saveChanges = saveChanges;

    function saveChanges() {

       if(vm.myForm.$valid) { 
            // Save to db or whatever.
            vm.myForm.$setPristine();
       }
}

Theo như tôi có thể thấy, mẫu không thể gọi phương thức "saveChanges", vì nó không được tiếp xúc với mẫu
Spock

2
Phương thức "saveChanges" được hiển thị trong dòng 3 của javascript hoặc tôi hiểu nhầm?
slopapa

3
điều này là tốt vì nó có nghĩa là bạn có thể tránh tiêm toàn bộ phạm vi $, theo ý kiến ​​của tôi
rõ ràng hơn

2
Làm thế nào để bạn kiểm tra điều này trong hoa nhài? Trong thông số kỹ thuật của tôi, vm.myForm không được xác định
bahrieinn

1
Điều này cần được lưu ý trong các tài liệu chính thức cho 1.5.X đó là cách để thực hiện các thành phần và es6. cảm ơn ngài
MatanCo

91

Bạn có thể đính kèm biểu mẫu vào một số đối tượng được xác định trong bộ điều khiển chính. Sau đó, bạn có thể đạt được hình thức của bạn ngay cả từ một phạm vi con.

Bộ điều khiển phụ huynh

$scope.forms = {};

Một số mẫu trong phạm vi con

<form name="forms.form1">
</form>

Vấn đề là hình thức không phải được xác định trong thời điểm mã trong bộ điều khiển được thực thi. Vì vậy, bạn phải làm một cái gì đó như thế này

$scope.$watch('forms.form1', function(form) {
  if(form) {
    // your code...
  }
});

10
Tôi khuyên bạn nên sử dụng var watcher = $scope.$watchervà bên trong câu lệnh if, bạn sẽ loại bỏ trình theo dõi () để hủy liên kết đồng hồ. Điều này làm cho nó trở thành đồng hồ 1 lần để bạn không xem mọi thông báo sau khi được đặt
willJk

91

Nếu bạn muốn truyền biểu mẫu cho bộ điều khiển cho mục đích xác thực, bạn có thể chỉ cần chuyển nó dưới dạng đối số cho phương thức xử lý việc gửi. Sử dụng tên biểu mẫu, vì vậy đối với câu hỏi ban đầu, nó sẽ giống như:

<button ng-click="submit(customerForm)">Save</button>

13
Để làm rõ cho những người đọc trong tương lai, nếu nói rằng biểu mẫu của bạn được đặt tên / định nghĩa tương tự như thế này <form name="myform"></form>hoặc thậm chí <div ng-form name="myform"></div>, thì sự kiện nhấp chuột của bạn sẽ như sau : ng-click="submit(myform)". Sau đó, bạn có thể truy cập đối tượng dạng Angular trong chức năng nhấp chuột của mình như: $scope.submit = function (form) { if (form.$valid) {v.v.
Matty J

Tôi tìm thấy một vấn đề ở đây - giả sử có một danh sách thả xuống trong biểu mẫu. Sử dụng phương pháp trên chỉ mang lại cho tôi giá trị xem chứ không phải giá trị chính xác mà tôi cần. Hoặc tôi đang làm bất cứ điều gì sai, sẽ thêm một fiddle.
swateek

82

Bit muộn cho một câu trả lời nhưng đi kèm với tùy chọn sau. Nó đang làm việc cho tôi nhưng không chắc nó có đúng cách hay không.

Theo quan điểm của tôi, tôi đang làm điều này:

<form name="formName">
    <div ng-init="setForm(formName);"></div>
</form>

Và trong bộ điều khiển:

$scope.setForm = function (form) {
    $scope.myForm = form;
}

Bây giờ sau khi làm điều này, tôi đã có biểu mẫu của mình trong biến điều khiển $scope.myForm


1
Điều duy nhất tôi thêm vào đây là chắc chắn đây là phần cuối của biểu mẫu.
smb

Vị trí của <div ng-init = "setForm (formName);"> </ div> không quan trọng. Chỉ cần cẩn thận rằng nó dưới hình thức.
waqas

1
tốt, nhưng tôi thích một giải pháp đơn giản hơn: ng-init = "$ Parent.myForm = formName" Không cần thay đổi bộ điều khiển Lưu ý: nó chỉ hoạt động với bộ điều khiển trực tiếp, trái với giải pháp trên
mastilver

Sau khi thử các phương thức khác, tôi giải quyết phương thức này vì nó cho phép namethuộc tính chính xác như những gì tôi muốn. Vấn đề với các giải pháp đối tượng giả khác là nếu thành phần này được sử dụng trong thành phần khác có dạng ng, thì dạng ng khác sử dụng tên biểu mẫu này theo nghĩa đen. Vì vậy, nó sẽ có một trường có tên chuỗi (KHÔNG thuộc tính lồng nhau) của "dummy.myForm", tôi thấy điều này không thể chấp nhận được.
Basil

Tôi đã thử và thất bại nhiều lần khi sử dụng cú pháp của bộ điều khiểnAs (Tôi đang làm việc với $ mdDialog). Cuối cùng giải quyết cho điều này và nó đã làm một công việc tuyệt vời. Chỉ lưu ý là mọi khởi tạo bộ điều khiển cần phải được chạy trong thời gian chờ $ vì biểu mẫu không khả dụng khi bộ điều khiển chạy lần đầu tiên
Peter Nixey

22

Để có thể truy cập biểu mẫu trong bộ điều khiển của bạn, bạn phải thêm nó vào một đối tượng phạm vi giả.

Cái gì đó như $scope.dummy = {}

Đối với tình huống của bạn, điều này có nghĩa là:

<form name="dummy.customerForm">

Trong bộ điều khiển của bạn, bạn sẽ có thể truy cập biểu mẫu bằng cách:

$scope.dummy.customerForm

và bạn sẽ có thể làm những thứ như

$scope.dummy.customerForm.$setPristine()

LIÊN KẾT WIKI

Có một '.' trong các mô hình của bạn sẽ đảm bảo rằng kế thừa nguyên mẫu đang hoạt động. Vì vậy, sử dụng <input type="text" ng-model="someObj.prop1">chứ không phải là<input type="text" ng-model="prop1">

Nếu bạn thực sự muốn / cần sử dụng một nguyên thủy, có hai cách giải quyết:

1.Sử dụng $ Parent.parentScopeProperty trong phạm vi con. Điều này sẽ ngăn phạm vi con tạo tài sản riêng của nó. 2. Xác định một hàm trên phạm vi cha và gọi nó từ con, truyền giá trị nguyên thủy lên tới cha mẹ (không phải lúc nào cũng có thể)


Đâu là khu vực hiệu quả để xác định ràng buộc mẫu?
Gus Crawford

giá trị đề cập của nó dummy.customerFormsẽ không được xác định cho đến khi các điều kiện ng-ifđược đáp ứng nếu phần tử biểu mẫu có ng-ifđiều kiện dựa trên nó
haxxxton

22

Câu trả lời này hơi muộn, nhưng tôi tình cờ tìm ra giải pháp giúp mọi thứ trở nên dễ dàng hơn rất nhiều.

Bạn thực sự có thể gán tên biểu mẫu trực tiếp cho bộ điều khiển của mình nếu bạn đang sử dụng cú pháp của bộ điều khiển và sau đó tham chiếu nó từ biến "này". Đây là cách tôi đã làm nó trong mã của mình:

Tôi đã cấu hình bộ điều khiển thông qua ui-router (nhưng bạn có thể làm điều đó theo cách bạn muốn, ngay cả trong HTML trực tiếp với một cái gì đó giống như <div ng-controller="someController as myCtrl">) Đây là giao diện của cấu hình ui-router:

views: {
            "": {
                templateUrl: "someTemplate.html",
                controller: "someController",
                controllerAs: "myCtrl"
            }
       }

và sau đó trong HTML, bạn chỉ cần đặt tên biểu mẫu là "tên bộ điều khiển". "tên" như vậy:

<ng-form name="myCtrl.someForm">
    <!-- example form code here -->
    <input name="firstName" ng-model="myCtrl.user.firstName" required>
</ng-form>

Bây giờ trong bộ điều khiển của bạn, bạn có thể chỉ cần làm điều này:

angular
.module("something")
.controller("someController",
    [
       "$scope",
        function ($scope) {
            var vm = this;
            if(vm.someForm.$valid){
              // do something
            }
    }]);

2
Mặc dù đây chủ yếu chỉ là cùng một kỹ thuật như một số câu trả lời khác gợi ý, nhưng đây là biến thể tốt nhất và nên là câu trả lời được chấp nhận, đặc biệt là vì mọi người đều sử dụng bộ điều khiển.
Dấu chấm phẩy

6

Có, bạn có thể truy cập một biểu mẫu trong bộ điều khiển (như đã nêu trong tài liệu ).

Ngoại trừ khi biểu mẫu của bạn không được xác định trong phạm vi điều khiển và được xác định trong phạm vi con thay thế.

Về cơ bản, một số chỉ thị góc, chẳng hạn như ng-if, ng-repeathoặc ng-include, sẽ tạo ra một phạm vi con bị cô lập. Vì vậy, bất kỳ chỉ thị tùy chỉnh với một scope: {}tài sản được xác định. Có lẽ, các thành phần nền tảng của bạn cũng theo cách của bạn.

Tôi đã có cùng một vấn đề khi giới thiệu một đơn giản ng-ifxung quanh <form>thẻ.

Xem những điều này để biết thêm:

Lưu ý: Tôi đề nghị bạn viết lại câu hỏi của bạn. Câu trả lời cho câu hỏi của bạn là nhưng vấn đề của bạn hơi khác:

Tôi có thể truy cập một biểu mẫu trong phạm vi con từ bộ điều khiển không?

Câu trả lời đơn giản là: không .


... trừ khi bạn thiết lập biểu mẫu và bộ điều khiển của mình như được mô tả trong câu trả lời của @ondrs (sử dụng $scope.forms = {}name="forms.form1")
marapet

Xin vui lòng xem câu trả lời ngay trên của bạn bởi KhalilRavanna. Bạn có thể truy cập biểu mẫu từ $ scope.formName. Ông cung cấp một ví dụ hoạt động
micahblu

3

thêm ng-model="$ctrl.formName"thuộc tính vào biểu mẫu của bạn và sau đó trong trình điều khiển, bạn có thể truy cập biểu mẫu dưới dạng một đối tượng bên trong trình điều khiển của mình bằng cáchthis.formName


0

Chắc chắn bạn không thể truy cập mẫu trong phạm vi bec. nó không được tạo ra DOM từ mẫu html được tải chậm một chút như trình xây dựng bộ điều khiển. giải pháp là xem cho đến khi DOM được tải và tất cả phạm vi được xác định!

trong bộ điều khiển:

$timeout(function(){
    console.log('customerForm:', $scope.customerForm);
    // everything else what you need
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.