2013-03-15 36 views
96

Giả sử tôi muốn thực hiện điều gì đó như tự động chạy một số mã (như lưu dữ liệu vào máy chủ) bất cứ khi nào giá trị của mô hình thay đổi. Là cách duy nhất để làm điều này bằng cách thiết lập một cái gì đó như ng-change trên mỗi điều khiển mà có thể có thể thay đổi mô hình?AngularJS: tự động phát hiện thay đổi trong mô hình

Tức là, với chế độ xem, mọi thứ sẽ thay đổi ngay khi mô hình được thay đổi mà không phải gắn kết bất kỳ thứ gì lên rõ ràng. Có một tương tự để có thể chạy mã tiết kiệm cho một máy chủ? Một cái gì đó như

myModel.on('change', function() { 
    $.post("/my-url", ...); 
}); 

như bạn có thể thấy với thứ gì đó như xương sống.

Trả lời

142

Trong giao diện với {{}} và/hoặc ng-model, Angular đang thiết lập $watch() es cho bạn đằng sau hậu trường.

Theo mặc định $watch so sánh theo tham chiếu. Nếu bạn đặt tham số thứ ba là $watch thành true, Góc thay vì "nông" sẽ xem đối tượng để thay đổi. Đối với mảng này có nghĩa là so sánh các mục mảng, đối với bản đồ đối tượng, điều này có nghĩa là xem các thuộc tính. Vì vậy, điều này sẽ làm những gì bạn muốn:

$scope.$watch('myModel', function() { ... }, true); 

Cập nhật: v1.2 góc thêm một phương pháp mới cho điều này, `$watchCollection():

$scope.$watchCollection('myModel', function() { ... }); 

Lưu ý rằng từ "nông cạn" được sử dụng để mô tả so sánh hơn là "sâu" vì các tham chiếu không được theo sau - ví dụ, nếu đối tượng được xem có chứa giá trị thuộc tính là tham chiếu đến đối tượng khác, tham chiếu đó không được theo sau để so sánh đối tượng khác.

+1

Ah, tuyệt vời! Có bất kỳ lý do này dường như không được tất cả các tài liệu (tức là, tôi không nghĩ rằng bất kỳ hướng dẫn trên trang web góc đề cập đến thiết lập đồng hồ $ trực tiếp)? Có bất cứ điều gì xấu về điều này mà sẽ làm cho thiết lập (có khả năng nhiều) 'ng-thay đổi móc trên đầu vào kiểm soát một ý tưởng tốt hơn? – Alec

+12

Vâng, sẽ rất tuyệt nếu hướng dẫn chính đề cập đến $ xem ở đâu đó.Điều gì là "xấu" về cách tiếp cận này là nó có thể tốn thời gian nếu mô hình của bạn lớn (mỗi chu kỳ tiêu hóa - mọi phím tắt trong một trường đầu vào - sẽ dẫn đến mô hình này bị kiểm tra sâu, có thể nhiều lần) . Trong trường hợp đó, chọn lọc $ watch() es hoặc chọn lọc ng-thay đổi sẽ tốt hơn. –

7

Và nếu bạn cần để tạo kiểu yếu tố hình thức của bạn theo đó là nhà nước (sửa đổi/không đổi) tự động hoặc để kiểm tra xem một số giá trị đã thực sự thay đổi, bạn có thể sử dụng các module sau đây, được phát triển bởi bản thân mình: https://github.com/betsol/angular-input-modified

Nó thêm các thuộc tính và phương thức bổ sung vào biểu mẫu và các phần tử con của nó. Với nó, bạn có thể kiểm tra xem một số phần tử có chứa dữ liệu mới hay thậm chí thử nghiệm nếu toàn bộ biểu mẫu có dữ liệu chưa được lưu mới.

Bạn có thể thiết lập đồng hồ sau: $scope.$watch('myForm.modified', handler) và trình xử lý của bạn sẽ được gọi nếu một số phần tử biểu mẫu thực sự chứa dữ liệu mới hoặc nếu nó được chuyển về trạng thái ban đầu.

Ngoài ra, bạn có thể sử dụng modified thuộc tính của các thành phần biểu mẫu riêng lẻ để thực sự giảm lượng dữ liệu được gửi đến máy chủ qua cuộc gọi AJAX. Không cần phải gửi dữ liệu không thay đổi.

Là phần thưởng, bạn có thể hoàn nguyên biểu mẫu của mình về trạng thái ban đầu thông qua phương thức reset() của biểu mẫu.

Bạn có thể tìm thấy bản demo của mô-đun ở đây: http://plnkr.co/edit/g2MDXv81OOBuGo6ORvdt?p=preview

Cheers!

+0

Có cách nào để kiểm tra điều này trong bộ điều khiển không. ví dụ: nếu nhấp vào nút x, tôi có thể thực hiện như một cửa sổ xác nhận hiển thị if (myform.modified) không? – Flash

+0

Tất nhiên, chỉ cần vượt qua FormController để chức năng điều khiển của bạn: '

', ''. –

+0

cảm ơn điều này sẽ làm điều gì đó chỉ khi biểu mẫu đã được sửa đổi phải không? – Flash

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