Câu hỏi làm thế nào để công việc ràng buộc và tiêu hóa trong AngularJS?


Một điều đặt AngularJS ra khỏi các khung công tác JavaScript-MVC khác là khả năng lặp lại các giá trị ràng buộc từ JavaScript vào HTML bằng cách sử dụng các ràng buộc. Góc làm điều này "tự động" khi bạn gán bất kỳ giá trị nào cho biến $ scope.

Nhưng tự động như thế nào? Đôi khi, Angular sẽ không nhận được sự thay đổi vì vậy tôi cần phải gọi $ scope. $ Apply () hoặc $ scope. $ Digest () để thông báo góc để nhận thay đổi. Đôi khi, khi tôi chạy một trong các phương thức đó thì nó sẽ phát ra lỗi và nói rằng thông báo đã được tiến hành.

Kể từ khi các ràng buộc (bất kỳ thứ gì bên trong {{}} niềng răng hoặc ng-thuộc tính) được lặp lại với eval thì điều này có nghĩa là Angular liên tục bỏ phiếu đối tượng $ scope để tìm các thay đổi và sau đó thực hiện một eval để đẩy những thay đổi đó vào DOM / HTML? Hoặc có AngularJS bằng cách nào đó đã tìm ra các biến ma thuật sử dụng để 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ề nó được hỗ trợ đầy đủ bởi tất cả các trình duyệt, vì vậy tôi nghi ngờ nó.

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


76
2017-09-17 16:57


gốc


Tôi tìm thấy phần trong docs.angularjs.org/guide/concepts#runtime bắt đầu bằng "Đây là giải thích về cách ví dụ Hello world đạt được hiệu ứng ràng buộc dữ liệu" hữu ích. - Mark Rajcok
Bài đăng này cũng hữu ích nếu bạn chưa thấy nó: 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: Angular's "khả năng lặp lại các giá trị ràng buộc từ JavaScript vào HTML bằng cách sử dụng các ràng buộc" giống như một cách khó hiểu để nói "ràng buộc dữ liệu". Và tại thời điểm này nó không thực sự đặt Angular ngoài các khung công tác khác như Ember hoặc React. Câu hỏi này rất hữu ích, đừng hiểu lầm tôi. Nhưng đoạn đầu tiên đó chỉ là một ý kiến ​​mà tôi tình cờ không đồng ý - tôi sẽ chỉnh sửa câu hỏi nhưng tôi không cảm thấy đủ thẩm quyền. - Jorge Orpinel


Các câu trả lời:


Ngoài các phần tài liệu tìm thấy bởi Mark Tôi nghĩ rằng chúng tôi 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 người dùng với đầu vào HTML ('bản văn', 'con số', 'url', 'e-mail', 'radio', 'checkbox'). AngularJS có inputDirective. liên kết đầu vào 'văn bản', 'số', 'url' và 'email' người xử lý người nghe cho các sự kiện 'đầu vào' hoặc 'phím'. Trình xử lý người nghe phạm vi cuộc gọi.. '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 người dùng với phần tử chọn. AngularJS có selectDirective với hành vi tương tự về sự kiện 'thay đổi'.
  3. Thay đổi định kỳ bằng cách sử dụng $ timeout service cũng vậy $ rootScope. $ áp dụng ().
  4. eventDirectives (ngClick, vv) cũng sử dụng phạm vi. $ áp dụng.
  5. $ http cũng sử dụng $ rootScope. $ áp dụng ().
  6. 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.

64
2017-09-19 08:52



+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


Khi bạn phát hiện ra nó không phải là bỏ phiếu, nhưng sử dụng vòng lặp thực thi nội bộ, đó là lý do tại sao bạn cần sử dụng $ apply () hoặc $ digest () để đưa mọi thứ vào trong chuyển động.

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


5
2017-09-19 00:23



Vậy công việc $ apply (someFn) như thế nào? Nội dung của someFn có được thực thi khi lặp lại áp dụng được thực thi không? - matsko
Với $ áp dụng mã được thực hiện trong phạm vi Góc, đó là chỉ để thông báo cho nó rằng bạn muốn thay đổi được tiêu hóa, 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 $ digest, bạn phải kiểm tra pha $: groups.google.com/d/msg/angular/FJwxJ-XbJaE/1NavZNQBhf4J - dain