Làm thế nào để liên kết và tiêu hóa hoạt động trong AngularJS?


76

Một điều làm nên sự khác biệt của AngularJS với các khung JavaScript-MVC khác là khả năng lặp lại các giá trị bị ràng buộc từ JavaScript sang HTML bằng cách sử dụng các liên kết. Angular thực hiện điều này "tự động" khi bạn gán bất kỳ giá trị nào cho biến $ scope.

Nhưng làm thế nào tự động là điều này? Đôi khi, Angular sẽ không thực hiện thay đổi, vì vậy tôi cần gọi $ scope. $ Apply () hoặc $ scope. $ Digan () để thông báo cho angle nhận thay đổi. Đôi khi khi tôi chạy một trong hai phương thức đó thì nó báo lỗi và thông báo rằng một thông báo đã được xử lý.

Vì các liên kết (bất kỳ thứ gì bên trong dấu ngoặc nhọn {{}} hoặc ng-thuộc tính) được lặp lại với eval nên điều này có nghĩa là Angular liên tục thăm dò đối tượng $ scope để tìm kiếm các thay đổi và sau đó thực hiện eval để đẩy các thay đổi đó vào DOM / HTML? Hoặc AngularJS bằng cách nào đó đã tìm ra cách sử dụng các biến ma thuật để kích hoạt các sự kiện được kích hoạt khi một giá trị biến thay đổi hoặc được gán? Tôi chưa bao giờ nghe nói về việc nó được hỗ trợ đầy đủ bởi tất cả các trình duyệt, vì vậy tôi nghi ngờ điều đó.

AngularJS theo dõi các ràng buộc và các biến phạm vi của nó như thế nào?


5
Tôi thấy phần trong docs.angularjs.org/guide/concept#runtime bắt đầu bằng "Đây là phần giải thích về cách ví dụ Hello world đạt được hiệu ứng liên kết dữ liệu" hữu ích.
Mark Rajcok

3
Bài đăng này cũng hữu ích nếu bạn chưa xem: stackoverflow.com/questions/9682092/databinding-in-angularjs/…
Gloopy

Nhận xét về đoạn khai báo đầu tiên của bạn: "Khả năng lặp lại các giá trị liên kết từ JavaScript sang HTML bằng cách sử dụng liên kết" của Angular nghe có vẻ giống như một cách khó hiểu khi nói "liên kết dữ liệu". Và tại thời điểm này, nó không thực sự đặt Angular ra khỏi các framework khác như Ember hay React. Câu hỏi rất hữu ích, đừng hiểu sai ý tôi. Nhưng đoạn đầu tiên đó chỉ là một ý kiến ​​mà tôi không đồng ý - Tôi sẽ chỉnh sửa câu hỏi nhưng tôi cảm thấy không đủ thẩm quyền.
Jorge Orpinel,

Câu trả lời:


64

Ngoài phần tài liệu do Mark tìm thấy, tôi nghĩ chúng ta có thể cố gắng liệt kê tất cả các nguồn thay đổi có thể có.

  1. Tương tác của người dùng với đầu vào HTML ( 'văn bản' , 'số' , 'url' , 'email' , 'radio' , 'hộp kiểm' ). AngularJS có inputDirective . Các đầu vào 'văn bản', 'số', 'url' và 'email' ràng buộc trình xử lý trình xử lý cho các sự kiện 'đầu vào' hoặc 'phím xuống'. Phạm vi cuộc gọi của trình xử lý trình xử lý . $ Áp dụng . 'radio' và 'checkbox' liên kết trình xử lý tương tự cho sự kiện nhấp chuột.
  2. Tương tác của người dùng với phần tử được chọn. AngularJS có selectDirective với hành vi tương tự trên sự kiện 'thay đổi'.
  3. Các thay đổi định kỳ bằng cách sử dụng dịch vụ $ timeout cũng do $ rootScope. $ Apply () .
  4. eventDirectives (ngClick, v.v.) cũng sử dụng phạm vi. $ áp dụng .
  5. $ http cũng sử dụng $ rootScope. $ apply () .
  6. Những thay đổi bên ngoài thế giới AngularJS nên sử dụng phạm vi. $ Áp dụng như bạn biết.

2
+1 cho điểm "5. $ http cũng sử dụng $ rootScope. $ Apply ()." Argh. Có ai biết tại sao họ làm điều này? Điều này rất khó chịu ...
gecco

5

Như bạn đã phát hiện ra, nó không phải là thăm dò mà là sử dụng vòng lặp thực thi nội bộ, vì vậy đó là lý do tại sao bạn cần sử dụng $ apply () hoặc $ digan () để đưa mọi thứ vào chuyển động.

Lời giải thích của Miško khá cặn kẽ , nhưng còn thiếu một chút là Angular chỉ đang cố gắng làm cho $ scope trở lại trạng thái bên trong rõ ràng bất cứ khi nào có bất cứ điều gì xảy ra trong ngữ cảnh của chính nó. Điều này có thể mất khá nhiều thời gian giữa các trạng thái của mô hình, vì vậy đó cũng là lý do tại sao bạn không thể dựa vào việc $ watch () chỉ kích hoạt một lần và cũng là lý do tại sao bạn nên cẩn thận với việc thiết lập thủ công quan hệ giữa các mô hình, nếu không bạn sẽ kết thúc làm mới vòng tròn.


Vậy $ apply (someFn) hoạt động như thế nào? Nội dung của someFn có được thực thi khi thực hiện lặp áp dụng không?
matsko vào

Với $ áp dụng, mã được thực thi trong phạm vi Angular, chỉ để thông báo rằng bạn muốn các thay đổi được tiêu hóa, hãy xem: docs.angularjs.org/api/ng.$rootScope.Scope#$apply
dain

Trong trường hợp bạn muốn ngăn chặn va chạm với $ tiêu hóa, bạn phải kiểm tra với $ giai đoạn: groups.google.com/d/msg/angular/FJwxJ-XbJaE/1NavZNQBhf4J
dain
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.