Liên kết dữ liệu hoạt động như thế nào trong AngularJS?

1974
Pashec 2012-03-14 00:16.

Làm thế nào để ràng buộc dữ liệu hoạt động trong AngularJSkhuôn khổ?

Tôi không tìm thấy chi tiết kỹ thuật trên trang web của họ . Nó ít nhiều rõ ràng về cách nó hoạt động khi dữ liệu được truyền từ chế độ xem sang mô hình. Nhưng làm cách nào AngularJS theo dõi các thay đổi của thuộc tính mô hình mà không có bộ định tuyến và bộ định tuyến?

Tôi thấy rằng có những người theo dõi JavaScript có thể thực hiện công việc này. Nhưng chúng không được hỗ trợ trong Internet Explorer 6 và Internet Explorer 7 . Vậy làm cách nào AngularJS biết rằng tôi đã thay đổi ví dụ như sau và phản ánh sự thay đổi này trên một khung nhìn?

myobject.myproperty="new value";

14 answers

2751
Misko Hevery 2012-03-14 13:47.

AngularJS ghi nhớ giá trị và so sánh nó với giá trị trước đó. Đây là cách kiểm tra độ bẩn cơ bản. Nếu có sự thay đổi về giá trị, thì nó sẽ kích hoạt sự kiện thay đổi.

Các $apply()phương pháp, đó là những gì bạn gọi khi bạn đang chuyển từ một thế giới phi AngularJS vào một thế giới AngularJS, gọi điện $digest(). Thông báo chỉ là kiểm tra bẩn cũ đơn giản. Nó hoạt động trên tất cả các trình duyệt và hoàn toàn có thể dự đoán được.

Để đối chiếu giữa kiểm tra bẩn (AngularJS) và thay đổi trình nghe ( KnockoutJS và Backbone.js ): Mặc dù kiểm tra bẩn có vẻ đơn giản và thậm chí không hiệu quả (tôi sẽ giải quyết vấn đề đó sau), nhưng hóa ra nó luôn đúng về mặt ngữ nghĩa, trong khi trình nghe thay đổi có rất nhiều trường hợp góc kỳ lạ và cần những thứ như theo dõi sự phụ thuộc để làm cho nó chính xác hơn về mặt ngữ nghĩa. Theo dõi sự phụ thuộc KnockoutJS là một tính năng thông minh cho một vấn đề mà AngularJS không có.

Các vấn đề với trình nghe thay đổi:

  • Cú pháp này rất tệ, vì các trình duyệt không hỗ trợ nó. Có, có những proxy, nhưng chúng không chính xác về mặt ngữ nghĩa trong mọi trường hợp và tất nhiên không có proxy nào trên các trình duyệt cũ. Điểm mấu chốt là kiểm tra bẩn cho phép bạn thực hiện POJO , trong khi KnockoutJS và Backbone.js buộc bạn phải kế thừa từ các lớp của chúng và truy cập dữ liệu của bạn thông qua trình truy cập.
  • Thay đổi sự kết hợp. Giả sử bạn có một mảng các mục. Giả sử bạn muốn thêm các mục vào một mảng, vì bạn đang lặp lại để thêm, mỗi khi bạn thêm, bạn sẽ kích hoạt các sự kiện thay đổi, đang hiển thị giao diện người dùng. Điều này rất không tốt cho hiệu suất. Những gì bạn muốn là cập nhật giao diện người dùng chỉ một lần vào cuối. Các sự kiện thay đổi quá chi tiết.
  • Thay đổi trình nghe kích hoạt ngay lập tức trên một trình thiết lập, đây là một vấn đề, vì trình xử lý thay đổi có thể thay đổi dữ liệu hơn nữa, điều này kích hoạt nhiều sự kiện thay đổi hơn. Điều này thật tệ vì trên ngăn xếp của bạn, bạn có thể có một số sự kiện thay đổi xảy ra cùng một lúc. Giả sử bạn có hai mảng cần được đồng bộ hóa vì bất kỳ lý do gì. Bạn chỉ có thể thêm vào một hoặc khác, nhưng mỗi khi thêm, bạn sẽ kích hoạt một sự kiện thay đổi, hiện có một cái nhìn không nhất quán về thế giới. Đây là một vấn đề rất giống với khóa luồng, mà JavaScript tránh vì mỗi lệnh gọi lại thực thi độc quyền và hoàn thành. Các sự kiện thay đổi phá vỡ điều này vì các trình thiết lập có thể gây ra những hậu quả sâu rộng không được dự kiến ​​và không rõ ràng, điều này tạo ra vấn đề chuỗi lặp lại. Hóa ra những gì bạn muốn làm là trì hoãn việc thực thi trình lắng nghe và đảm bảo rằng chỉ có một trình nghe chạy tại một thời điểm, do đó bất kỳ mã nào cũng có thể tự do thay đổi dữ liệu và nó biết rằng không có mã nào khác chạy khi đang làm như vậy .

Còn về hiệu suất thì sao?

Vì vậy, có vẻ như chúng tôi đang chậm, vì việc kiểm tra bẩn không hiệu quả. Đây là lúc chúng ta cần xem xét các số thực thay vì chỉ có các đối số lý thuyết, nhưng trước tiên hãy xác định một số ràng buộc.

Con người là:

  • Chậm - Bất cứ thứ gì nhanh hơn 50 ms đều không thể nhận thấy đối với con người và do đó có thể được coi là "tức thì".

  • Hạn chế - Bạn thực sự không thể hiển thị hơn 2000 mẩu thông tin cho một người trên một trang. Bất cứ điều gì hơn thế đều là giao diện người dùng thực sự tệ và con người không thể xử lý điều này.

Vậy câu hỏi thực sự là: Bạn có thể thực hiện bao nhiêu phép so sánh trên một trình duyệt trong 50 mili giây? Đây là một câu hỏi khó trả lời vì có nhiều yếu tố tác động, nhưng đây là một trường hợp thử nghiệm:http://jsperf.com/angularjs-digest/6tạo ra 10.000 người theo dõi. Trên trình duyệt hiện đại, quá trình này chỉ mất dưới 6 mili giây. Trên Internet Explorer 8 , mất khoảng 40 mili giây. Như bạn có thể thấy, đây không phải là vấn đề ngay cả trên các trình duyệt chậm ngày nay. Có một lưu ý: Các phép so sánh cần đơn giản để phù hợp với giới hạn thời gian ... Thật không may, việc thêm một phép so sánh chậm vào AngularJS quá dễ dàng, vì vậy bạn rất dễ xây dựng các ứng dụng chậm khi bạn không biết gì về mình. đang làm. Nhưng chúng tôi hy vọng sẽ có câu trả lời bằng cách cung cấp một mô-đun thiết bị đo lường, mô-đun này sẽ cho bạn thấy đâu là những so sánh chậm.

Hóa ra là các trò chơi điện tử và GPU sử dụng phương pháp kiểm tra độ bẩn, đặc biệt vì nó nhất quán. Miễn là chúng đạt được tốc độ làm tươi màn hình (thường là 50-60 Hz hoặc 16,6-20 ms một lần), thì bất kỳ hiệu suất nào vượt quá đó đều là lãng phí, vì vậy tốt hơn bạn nên vẽ nhiều thứ hơn là tăng FPS cao hơn.

325
MW. 2013-08-23 03:28.

Misko đã đưa ra một mô tả tuyệt vời về cách hoạt động của các liên kết dữ liệu, nhưng tôi muốn thêm quan điểm của mình về vấn đề hiệu suất với liên kết dữ liệu.

Như Misko đã nói, khoảng 2000 ràng buộc là nơi bạn bắt đầu thấy vấn đề, nhưng dù sao thì bạn cũng không nên có hơn 2000 mẩu thông tin trên một trang. Điều này có thể đúng, nhưng không phải mọi ràng buộc dữ liệu đều hiển thị cho người dùng. Khi bạn bắt đầu xây dựng bất kỳ loại tiện ích con hoặc lưới dữ liệu nào với liên kết hai chiều, bạn có thể dễ dàng đạt được 2000 liên kết mà không gặp phải UX xấu.

Ví dụ: hãy xem xét một hộp tổ hợp nơi bạn có thể nhập văn bản để lọc các tùy chọn có sẵn. Loại điều khiển này có thể có ~ 150 mục và vẫn có thể sử dụng được. Nếu nó có một số tính năng bổ sung (ví dụ: một lớp cụ thể trên tùy chọn hiện được chọn), bạn bắt đầu nhận được 3-5 ràng buộc cho mỗi tùy chọn. Đặt ba trong số các tiện ích này trên một trang (ví dụ: một để chọn quốc gia, một để chọn một thành phố ở quốc gia đã nói và thứ ba để chọn khách sạn) và bạn đã ở đâu đó từ 1000 đến 2000 ràng buộc rồi.

Hoặc xem xét một lưới dữ liệu trong một ứng dụng web của công ty. 50 hàng mỗi trang không phải là không hợp lý, mỗi hàng có thể có 10-20 cột. Nếu bạn xây dựng điều này với ng-repeat, và / hoặc có thông tin trong một số ô sử dụng một số liên kết, bạn có thể đạt tới 2000 liên kết chỉ với lưới này.

Tôi thấy đây là một vấn đề lớn khi làm việc với AngularJS và giải pháp duy nhất mà tôi có thể tìm được cho đến nay là tạo các widget mà không sử dụng ràng buộc hai chiều, thay vì sử dụng ngOnce, các trình theo dõi hủy đăng ký và các thủ thuật tương tự hoặc cấu trúc các lệnh xây dựng DOM với thao tác jQuery và DOM. Tôi cảm thấy điều này đánh bại mục đích sử dụng Angular ngay từ đầu.

Tôi rất muốn nghe các gợi ý về các cách khác để xử lý vấn đề này, nhưng có lẽ tôi nên viết câu hỏi của riêng mình. Tôi muốn đưa điều này vào một bình luận, nhưng hóa ra là quá lâu cho điều đó ...

TL; DR
Việc liên kết dữ liệu có thể gây ra các vấn đề về hiệu suất trên các trang phức tạp.

161
superluminary 2015-06-03 02:31.

Bằng cách kiểm tra bẩn $scopeđối tượng

Angular duy trì một đơn giản arraynhững người theo dõi trong các $scopeđối tượng. Nếu bạn kiểm tra bất kỳ, $scopebạn sẽ thấy rằng nó chứa một arrayđược gọi $$watchers.

Mỗi người xem là một objectcái chứa trong số những thứ khác

  1. Một biểu thức mà người xem đang theo dõi. Đây có thể chỉ là một attributecái tên hoặc một cái gì đó phức tạp hơn.
  2. Giá trị cuối cùng đã biết của biểu thức. Điều này có thể được kiểm tra với giá trị tính toán hiện tại của biểu thức. Nếu các giá trị khác nhau, trình xem sẽ kích hoạt chức năng và đánh dấu $scopelà bẩn.
  3. Một chức năng sẽ được thực thi nếu trình theo dõi bị bẩn.

Cách xác định người theo dõi

Có nhiều cách khác nhau để xác định một người theo dõi trong AngularJS.

  • Bạn có thể rõ ràng $watchmột attributetrên $scope.

      $scope.$watch('person.username', validateUnique);
    
  • Bạn có thể đặt một {{}}phép nội suy trong mẫu của mình (một người theo dõi sẽ được tạo cho bạn hiện tại $scope).

      <p>username: {{person.username}}</p>
    
  • Bạn có thể yêu cầu một chỉ thị ng-modelđể xác định trình theo dõi cho bạn.

      <input ng-model="person.username" />
    

Các $digestchu kỳ kiểm tra tất cả sát chống lại giá trị cuối cùng của họ

Khi chúng ta tương tác với AngularJS thông qua các kênh bình thường (ng-model, ng-repeat, v.v.), một chu trình thông báo sẽ được kích hoạt bởi chỉ thị.

Một chu kỳ tiêu hóa là một chu trình xem xét theo chiều sâu của $scopevà tất cả các con của nó . Đối với mỗi biểu thức $scope object, chúng tôi lặp lại nó $$watchers arrayvà đánh giá tất cả các biểu thức. Nếu giá trị biểu thức mới khác với giá trị đã biết cuối cùng, thì hàm của watcher sẽ được gọi. Hàm này có thể biên dịch lại một phần của DOM, tính toán lại một giá trị trên $scope, kích hoạt một AJAX request, bất cứ điều gì bạn cần nó làm.

Mọi phạm vi đều được duyệt và mọi biểu thức đồng hồ được đánh giá và kiểm tra so với giá trị cuối cùng.

Nếu một trình theo dõi được kích hoạt, tức $scope

Nếu một trình theo dõi được kích hoạt, ứng dụng sẽ biết có điều gì đó đã thay đổi và $scopebị đánh dấu là bẩn.

Các hàm của Watcher có thể thay đổi các thuộc tính khác trên $scopehoặc trên phụ huynh $scope. Nếu một $watcherchức năng đã được kích hoạt, chúng tôi không thể đảm bảo rằng các chức năng khác của chúng tôi $scopevẫn sạch và vì vậy chúng tôi thực hiện lại toàn bộ chu trình thông báo.

Điều này là do AngularJS có ràng buộc hai chiều, vì vậy dữ liệu có thể được chuyển ngược lại $scopecây. Chúng tôi có thể thay đổi giá trị trên giá trị cao hơn $scopeđã được tiêu hóa. Có lẽ chúng ta thay đổi một giá trị trên $rootScope.

Nếu $digestbị bẩn, chúng tôi thực hiện lại toàn bộ $digestchu trình

Chúng tôi liên tục lặp lại $digestchu trình cho đến khi chu trình thông báo trở nên sạch sẽ (tất cả các $watchbiểu thức có cùng giá trị như chúng có trong chu kỳ trước đó) hoặc chúng tôi đạt đến giới hạn thông báo. Theo mặc định, giới hạn này được đặt là 10.

Nếu chúng ta đạt đến giới hạn thông báo thì AngularJS sẽ xuất hiện lỗi trong bảng điều khiển:

10 $digest() iterations reached. Aborting!

Thông báo khó trên máy nhưng dễ đối với nhà phát triển

Như bạn có thể thấy, mỗi khi có gì đó thay đổi trong ứng dụng AngularJS, AngularJS sẽ kiểm tra từng người theo dõi trong $scopehệ thống phân cấp để xem cách phản hồi. Đối với một nhà phát triển, đây là một lợi ích lớn về năng suất, vì bây giờ bạn hầu như không cần viết mã nối dây, AngularJS sẽ chỉ thông báo nếu một giá trị đã thay đổi và làm cho phần còn lại của ứng dụng phù hợp với thay đổi.

Từ góc độ của máy, điều này thực sự không hiệu quả và sẽ làm chậm ứng dụng của chúng tôi nếu chúng tôi tạo quá nhiều người theo dõi. Misko đã trích dẫn một con số khoảng 4000 người theo dõi trước khi ứng dụng của bạn cảm thấy chậm trên các trình duyệt cũ hơn.

Ví dụ, bạn có thể dễ dàng đạt đến giới hạn này nếu ng-repeatvượt quá mức lớn JSON array. Bạn có thể giảm thiểu điều này bằng cách sử dụng các tính năng như liên kết một lần để biên dịch mẫu mà không cần tạo trình theo dõi.

Cách tránh tạo quá nhiều người theo dõi

Mỗi khi người dùng tương tác với ứng dụng của bạn, mọi người xem trong ứng dụng của bạn sẽ được đánh giá ít nhất một lần. Một phần quan trọng của việc tối ưu hóa ứng dụng AngularJS là giảm số lượng người theo dõi trong $scopecây của bạn . Một cách dễ dàng để làm điều này là ràng buộc một thời gian .

Nếu bạn có dữ liệu hiếm khi thay đổi, bạn có thể liên kết dữ liệu đó chỉ một lần bằng cách sử dụng cú pháp ::, như sau:

<p>{{::person.username}}</p>

hoặc là

<p ng-bind="::person.username"></p>

Liên kết sẽ chỉ được kích hoạt khi mẫu chứa được hiển thị và dữ liệu được tải vào $scope.

Điều này đặc biệt quan trọng khi bạn có ng-repeatnhiều mục.

<div ng-repeat="person in people track by username">
  {{::person.username}}
</div>
82
Pete BD 2012-03-14 11:01.

Đây là hiểu biết cơ bản của tôi. Nó cũng có thể là sai!

  1. Các mục được theo dõi bằng cách chuyển một hàm (trả về điều cần theo dõi) cho $watchphương thức.
  2. Các thay đổi đối với các mục đã xem phải được thực hiện trong một khối mã được bao bọc bởi $applyphương thức này.
  3. Vào cuối của $applycác $digestphương pháp được gọi mà đi qua mỗi đồng hồ và kiểm tra xem nếu họ thay đổi kể từ lần cuối cùng $digestran.
  4. Nếu tìm thấy bất kỳ thay đổi nào thì thông báo sẽ được gọi lại cho đến khi tất cả các thay đổi ổn định.

Trong quá trình phát triển bình thường, cú pháp liên kết dữ liệu trong HTML yêu cầu trình biên dịch AngularJS tạo đồng hồ cho bạn và các phương thức bộ điều khiển đã được chạy bên trong $apply. Vì vậy, đối với nhà phát triển ứng dụng, tất cả đều minh bạch.

63
jpsimons 2012-09-04 07:45.

Tôi đã tự hỏi điều này trong một thời gian. Nếu không có bộ cài đặt thì làm thế nào để AngularJSthông báo thay đổi $scopeđối tượng? Nó có thăm dò ý kiến ​​của họ không?

Những gì nó thực sự làm là thế này: Bất kỳ vị trí "bình thường" nào mà bạn sửa đổi mô hình đã được gọi từ phần ruột của AngularJSnó, vì vậy nó sẽ tự động gọi $applycho bạn sau khi mã của bạn chạy. Giả sử bộ điều khiển của bạn có một phương thức được kết nối với ng-clickmột phần tử nào đó. Vì kết AngularJSnối việc gọi phương thức đó lại với nhau cho bạn, nên nó có cơ hội thực hiện $applyở một nơi thích hợp. Tương tự như vậy, đối với các biểu thức xuất hiện ngay trong các khung nhìn, chúng được thực thi bởi AngularJSvì vậy nó thực hiện $apply.

Khi tài liệu nói về việc phải gọi $applythủ công cho mã bên ngoàiAngularJS , nó nói về mã, khi chạy, không xuất phát từ AngularJSchính nó trong ngăn xếp cuộc gọi.

33
Nicolas Zozol 2016-05-21 03:33.

Giải thích bằng Hình ảnh:

Data-Binding cần một ánh xạ

Tham chiếu trong phạm vi không chính xác là tham chiếu trong mẫu. Khi bạn ràng buộc dữ liệu hai đối tượng, bạn cần đối tượng thứ ba lắng nghe đối tượng đầu tiên và sửa đổi đối tượng kia.

Tại đây, khi bạn sửa đổi <input>, bạn chạm vào data-ref3 . Và chủ nghĩa ràng buộc dữ liệu cổ điển sẽ thay đổi data-ref4 . Vậy các {{data}}biểu thức khác sẽ di chuyển như thế nào?

Sự kiện dẫn đến $ tiêu hóa ()

Angular duy trì một oldValuenewValuemọi ràng buộc. Và sau mỗi sự kiện Angular , $digest()vòng lặp nổi tiếng sẽ kiểm tra WatchList để xem có điều gì đó thay đổi hay không. Những sự kiện gócng-click, ng-change, $httphoàn thành ... Các $digest()ý loop chừng như bất kỳ oldValuekhác với các newValue.

Trong hình trước, nó sẽ nhận thấy rằng data-ref1 và data-ref2 đã thay đổi.

Kết luận

Nó hơi giống với Trứng và Gà. Bạn không bao giờ biết ai bắt đầu, nhưng hy vọng nó hoạt động hầu hết thời gian như mong đợi.

Điểm khác là bạn có thể hiểu dễ dàng tác động sâu sắc của một ràng buộc đơn giản đối với bộ nhớ và CPU. Hy vọng rằng Máy tính để bàn đủ chất béo để xử lý điều này. Điện thoại di động không phải là mạnh.

22
Sasank Sunkavalli 2016-05-23 08:18.

Rõ ràng là không có sự kiểm tra định kỳ về Scopeviệc có bất kỳ thay đổi nào trong các Đối tượng gắn liền với nó hay không. Không phải tất cả các đối tượng được gắn vào phạm vi đều được theo dõi. Phạm vi duy trì một $$ watchers theo nguyên mẫu . Scopechỉ lặp qua điều này $$watcherskhi $digestđược gọi.

Angular thêm một người theo dõi vào $$ watchers cho mỗi người trong số này

  1. {{biểu thức}} - Trong các mẫu của bạn (và bất kỳ nơi nào khác có biểu thức) hoặc khi chúng tôi xác định ng-model.
  2. $scope.$watch ('expression / function') - Trong JavaScript của bạn, chúng tôi chỉ có thể đính kèm một đối tượng phạm vi cho góc để xem.

Hàm $ watch có ba tham số:

  1. Đầu tiên là một hàm watcher chỉ trả về đối tượng hoặc chúng ta có thể thêm một biểu thức.

  2. Thứ hai là một hàm lắng nghe sẽ được gọi khi có sự thay đổi trong đối tượng. Tất cả những thứ như thay đổi DOM sẽ được thực hiện trong chức năng này.

  3. Thứ ba là một tham số tùy chọn nhận trong một boolean. Nếu góc thật, sâu của nó quan sát đối tượng & nếu Angular sai của nó chỉ thực hiện một tham chiếu quan sát trên đối tượng. Triển khai thô của $ watch trông như thế này

Scope.prototype.$watch = function(watchFn, listenerFn) { var watcher = { watchFn: watchFn, listenerFn: listenerFn || function() { }, last: initWatchVal // initWatchVal is typically undefined }; this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers  
};

Có một điều thú vị trong Angular được gọi là Digest Cycle. Các$digest cycle starts as a result of a call to $phạm vi.$digest(). Assume that you change a $mô hình phạm vi trong một hàm xử lý thông qua chỉ thị ng-click. Trong trường hợp đó, AngularJS tự động kích hoạt$digest cycle by calling $tiêu hóa (). Ngoài ng-click, có một số chỉ thị / dịch vụ tích hợp sẵn khác cho phép bạn thay đổi mô hình (ví dụ: ng-model, $timeout, etc) and automatically trigger a $chu kỳ tiêu hóa. Quá trình triển khai sơ bộ của $ tiêu hóa trông như thế này.

Scope.prototype.$digest = function() {
      var dirty;
      do {
          dirty = this.$$digestOnce(); } while (dirty); } Scope.prototype.$$digestOnce = function() {
   var self = this;
   var newValue, oldValue, dirty;
   _.forEach(this.$$watchers, function(watcher) {
          newValue = watcher.watchFn(self);
          oldValue = watcher.last;   // It just remembers the last value for dirty checking
          if (newValue !== oldValue) { //Dirty checking of References 
   // For Deep checking the object , code of Value     
   // based checking of Object should be implemented here
             watcher.last = newValue;
             watcher.listenerFn(newValue,
                  (oldValue === initWatchVal ? newValue : oldValue),
                   self);
          dirty = true;
          }
     });
   return dirty;
 };

Nếu chúng tôi sử dụng hàm setTimeout () của JavaScript để cập nhật mô hình phạm vi, Angular không có cách nào biết bạn có thể thay đổi những gì. Trong trường hợp này, chúng tôi có trách nhiệm gọi $ apply () theo cách thủ công, điều này sẽ kích hoạt$digest cycle. Similarly, if you have a directive that sets up a DOM event listener and changes some models inside the handler function, you need to call $apply () để đảm bảo các thay đổi có hiệu lực. Ý tưởng lớn của$apply is that we can execute some code that isn't aware of Angular, that code may still change things on the scope. If we wrap that code in $nộp đơn, nó sẽ lo việc gọi điện $digest(). Rough implementation of $ứng dụng().

Scope.prototype.$apply = function(expr) { try { return this.$eval(expr); //Evaluating code in the context of Scope
       } finally {
         this.$digest();
       }
};
16
Bharath Kumar 2016-05-17 05:05.

AngularJS xử lý cơ chế ràng buộc dữ liệu với sự trợ giúp của ba hàm mạnh mẽ: $ watch () , $ digan () và $ apply () . Hầu hết thời gian AngularJS sẽ gọi $ scope.$watch() and $phạm vi. $ tiêu hóa (), nhưng trong một số trường hợp, bạn có thể phải gọi các hàm này theo cách thủ công để cập nhật các giá trị mới.

$ watch () : -

Hàm này được sử dụng để quan sát những thay đổi trong một biến trên phạm vi $. Nó chấp nhận ba tham số: biểu thức, trình nghe và đối tượng bình đẳng, trong đó trình nghe và đối tượng bình đẳng là các tham số tùy chọn.

$ thông báo () -

Chức năng này lặp lại qua tất cả các đồng hồ trong $scope object, and its child $đối tượng phạm vi
(nếu có). Khi nào$digest() iterates over the watches, it checks if the value of the expression has changed. If the value has changed, AngularJS calls the listener with new value and old value. The $Hàm digan () được gọi bất cứ khi nào AngularJS cho rằng nó là cần thiết. Ví dụ: sau một lần nhấp vào nút hoặc sau một cuộc gọi AJAX. Bạn có thể gặp một số trường hợp AngularJS không gọi hàm $ digan () cho bạn. Trong trường hợp đó bạn phải tự gọi nó.

$ apply () -

Angular tự động cập nhật một cách kỳ diệu chỉ những thay đổi mô hình nằm trong ngữ cảnh AngularJS. Khi bạn thay đổi bất kỳ mô hình nào bên ngoài ngữ cảnh Angular (như sự kiện DOM của trình duyệt, setTimeout, XHR hoặc thư viện của bên thứ ba), thì bạn cần thông báo cho Angular về những thay đổi bằng cách gọi$apply() manually. When the $Kết thúc cuộc gọi hàm apply () AngularJS gọi nội bộ $ dig (), vì vậy tất cả các ràng buộc dữ liệu đều được cập nhật.

7
gartox 2013-09-18 19:57.

Tình cờ là tôi cần liên kết mô hình dữ liệu của một người với biểu mẫu, những gì tôi đã làm là ánh xạ trực tiếp dữ liệu với biểu mẫu.

Ví dụ: nếu mô hình có một cái gì đó như:

$scope.model.people.name

Đầu vào điều khiển của biểu mẫu:

<input type="text" name="namePeople" model="model.people.name">

Bằng cách đó nếu bạn sửa đổi giá trị của bộ điều khiển đối tượng, điều này sẽ được phản ánh tự động trong dạng xem.

Một ví dụ mà tôi đã thông qua mô hình được cập nhật từ dữ liệu máy chủ là khi bạn yêu cầu mã zip và mã zip dựa trên tải văn bản, danh sách các thuộc địa và thành phố được liên kết với chế độ xem đó và theo mặc định đặt giá trị đầu tiên với người dùng. Và điều này tôi đã làm rất tốt, điều xảy ra là angularJSđôi khi mất vài giây để làm mới mô hình, để làm điều này, bạn có thể đặt một con quay trong khi hiển thị dữ liệu.

6
Shankar Gangadhar 2017-06-18 09:28.
  1. Liên kết dữ liệu một chiều là một cách tiếp cận trong đó một giá trị được lấy từ mô hình dữ liệu và được chèn vào một phần tử HTML. Không có cách nào để cập nhật mô hình từ chế độ xem. Nó được sử dụng trong các hệ thống khuôn mẫu cổ điển. Các hệ thống này liên kết dữ liệu chỉ theo một hướng.

  2. Liên kết dữ liệu trong ứng dụng Angular là sự đồng bộ hóa dữ liệu tự động giữa các thành phần mô hình và chế độ xem.

Liên kết dữ liệu cho phép bạn coi mô hình như một nguồn chân lý duy nhất trong ứng dụng của bạn. Chế độ xem là hình chiếu của mô hình tại mọi thời điểm. Nếu mô hình được thay đổi, khung nhìn sẽ phản ánh sự thay đổi và ngược lại.

5
AllJs 2016-04-07 08:15.

Đây là một ví dụ về liên kết dữ liệu với AngularJS, sử dụng một trường đầu vào. Tôi sẽ giải thích sau

Mã HTML

<div ng-app="myApp" ng-controller="myCtrl" class="formInput">
     <input type="text" ng-model="watchInput" Placeholder="type something"/>
     <p>{{watchInput}}</p> 
</div>

Mã AngularJS

myApp = angular.module ("myApp", []);
myApp.controller("myCtrl", ["$scope", function($scope){
  //Your Controller code goes here
}]);

Như bạn có thể thấy trong ví dụ trên, AngularJS sử dụng ng-modelđể lắng nghe và xem những gì xảy ra trên các phần tử HTML, đặc biệt là trên inputcác trường. Khi điều gì đó xảy ra, hãy làm điều gì đó. Trong trường hợp của chúng tôi, ng-modelđược liên kết với chế độ xem của chúng tôi, sử dụng ký hiệu ria mép {{}}. Bất kỳ nội dung nào được nhập bên trong trường nhập sẽ hiển thị trên màn hình ngay lập tức. Và đó là vẻ đẹp của ràng buộc dữ liệu, sử dụng AngularJS ở dạng đơn giản nhất.

Hi vọng điêu nay co ich.

Xem một ví dụ làm việc tại đây trên Codepen

5
ojus kulkarni 2016-09-02 21:35.

AngularJs hỗ trợ liên kết dữ liệu hai chiều .
Có nghĩa là bạn có thể truy cập dữ liệu View -> Controller & Controller -> View

Đối với Ex.

1)

// If $scope have some value in Controller. $scope.name = "Peter";

// HTML
<div> {{ name }} </div>

O / P

Peter

Bạn có thể liên kết dữ liệu trong ng-modelLike: -
2)

<input ng-model="name" />

<div> {{ name }} </div>

Ở đây, trong ví dụ trên, bất cứ thứ gì người dùng nhập sẽ đưa ra, Nó sẽ được hiển thị trong <div>thẻ.

Nếu muốn liên kết đầu vào từ html với bộ điều khiển: -
3)

<form name="myForm" ng-submit="registration()">
   <label> Name </lbel>
   <input ng-model="name" />
</form>

Ở đây, nếu bạn muốn sử dụng đầu vào nametrong bộ điều khiển,

$scope.name = {}; $scope.registration = function() {
   console.log("You will get the name here ", $scope.name);
};

ng-modelliên kết chế độ xem của chúng tôi và kết xuất nó trong biểu thức {{ }}.
ng-modellà dữ liệu được hiển thị cho người dùng trong chế độ xem và người dùng tương tác với nó.
Vì vậy rất dễ ràng buộc dữ liệu trong AngularJs.

4
Shankar Gangadhar 2016-10-31 13:20.

Angular.js tạo một trình theo dõi cho mọi mô hình chúng tôi tạo trong chế độ xem. Bất cứ khi nào một mô hình được thay đổi, một lớp "ng-dirty" được thêm vào mô hình đó, do đó, người theo dõi sẽ quan sát tất cả các mô hình có lớp "ng-dirty" và cập nhật giá trị của chúng trong bộ điều khiển & ngược lại.

3
Dhana 2018-07-06 01:38.

ràng buộc dữ liệu:

Dữ liệu ràng buộc là gì?

Bất cứ khi nào người dùng thay đổi dữ liệu trong dạng xem, sẽ xảy ra một bản cập nhật về thay đổi đó trong mô hình phạm vi và chuyển đổi ngược lại.

Làm thế nào là nó có thể?

Câu trả lời ngắn gọn: Với sự trợ giúp của chu trình tiêu hóa.

Mô tả: Angular js đặt trình theo dõi trên mô hình phạm vi, chức năng này sẽ kích hoạt chức năng lắng nghe nếu có thay đổi trong mô hình.

$scope.$watch('modelVar' , function(newValue,oldValue){

// Mã cập nhật Dom với giá trị mới

});

Vậy hàm watcher được gọi khi nào và như thế nào?

Hàm Watcher được gọi là một phần của chu trình thông báo.

Chu kỳ thông báo được gọi tự động được kích hoạt như một phần của js góc được tích hợp trong các chỉ thị / dịch vụ như ng-model, ng-bind, $ timeout, ng-click và các thứ khác .. cho phép bạn kích hoạt chu kỳ thông báo.

Chức năng chu kỳ tiêu hóa:

$scope.$digest() -> digest cycle against the current scope. $scope.$apply() -> digest cycle against the parent scope 

I E$rootScope.$apply()

Lưu ý: $ apply () bằng $rootScope.$tiêu hóa () điều này có nghĩa là kiểm tra bẩn bắt đầu ngay từ gốc hoặc trên cùng hoặc phạm vi cha cho đến tất cả các phạm vi con $ trong ứng dụng js góc.

Các tính năng trên hoạt động trong trình duyệt IE cho các phiên bản được đề cập cũng chỉ bằng cách đảm bảo rằng ứng dụng của bạn là ứng dụng js góc có nghĩa là bạn đang sử dụng tệp kịch bản khung Angjs được tham chiếu trong thẻ tập lệnh.

Cảm ơn bạn.

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Xem đoạn giới thiệu cho bộ phim chuyển thể đầy khói lửa, có sự góp mặt của ngôi sao Edward Norton từ phim Motherless Brooklyn của Jonathan Lethem

Xem đoạn giới thiệu cho bộ phim chuyển thể đầy khói lửa, có sự góp mặt của ngôi sao Edward Norton từ phim Motherless Brooklyn của Jonathan Lethem

Edward Norton đã muốn đưa cuốn tiểu thuyết Motherless Brooklyn của Jonathan Lethem's Joycean 1999 lên màn ảnh kể từ khi nó được xuất bản. Bây giờ, 20 năm sau, một đoạn giới thiệu đã xuất hiện cho câu chuyện sôi nổi, đưa câu chuyện của Lethem trở lại những năm 1950 với rất nhiều gương mặt quen thuộc.

Cách dễ dàng chọn không tham gia trọng tài ràng buộc thẻ Apple

Cách dễ dàng chọn không tham gia trọng tài ràng buộc thẻ Apple

Có thích thú khi sử dụng Thẻ Apple mới của bạn không? Trước khi bạn bắt đầu chi tiêu, có một nhiệm vụ bổ sung cần xem xét: chọn không tham gia trọng tài ràng buộc. Bạn sẽ phát hiện ra các điều khoản trọng tài ràng buộc trong nhiều thỏa thuận tài chính vì nó giúp ngăn các ngân hàng và đối tác kinh doanh của họ không phải ra tòa.

Những người chơi Fortnite World Cup không ghi bàn có cảm giác hài hước về điều đó

Những người chơi Fortnite World Cup không ghi bàn có cảm giác hài hước về điều đó

Điểm số tại vòng chung kết Fortnite World Cup Solo hôm nay là rất lớn, với người chiến thắng Bugha ghi được nhiều hơn 26 điểm so với người về thứ hai là Psalm. Nhưng không phải ai cũng có thể giành chiến thắng: Bốn cầu thủ ra về với 0 điểm, nhưng — ít nhất là trên Twitter — họ là những người thể thao tốt về điều đó.

Báo cáo: Cánh cửa tuyển sinh có thể đã mở cho các ứng viên UCLA có mối quan hệ có ảnh hưởng

Báo cáo: Cánh cửa tuyển sinh có thể đã mở cho các ứng viên UCLA có mối quan hệ có ảnh hưởng

Huấn luyện viên trưởng của bộ môn thể dục dụng cụ UCLA Valorie Kondos-Field theo dõi Katelyn Ohashi thi đấu thăng bằng trong trận gặp Stanford tại Pauley Pavilion vào ngày 10 tháng 3 năm 2019 ở Los Angeles, California. Vụ bê bối gian lận tuyển sinh đại học tiết lộ các chi tiết của một quá trình chính thức hóa để đưa những đứa trẻ thất bại của các gia đình giàu có và nổi tiếng vào các trường đại học đáng tin cậy và danh tiếng, sử dụng một "cửa phụ" đắt tiền cho các bậc cha mẹ mà sự giàu có của họ khiến họ không có cơ hội. chỉ cần tài trợ cho một cánh mới trong khuôn viên trường.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Tầm nhìn đám mây phi tập trung của DFINITY Blockchain

Lưu ý của người biên tập: Bạn đang xem tài liệu lỗi thời từ blog DFINITY đang được bảo quản cho mục đích lưu trữ.

Tầm nhìn đám mây phi tập trung của DFINITY Blockchain

Bài đăng này khám phá tầm nhìn về đám mây phi tập trung của nhóm DFINITY và cách nó liên quan đến các nhà cung cấp blockchain truyền thống và đám mây hiện có như Amazon Web Services. Các minh chứng về công nghệ DFINITY được áp dụng bởi một mạng lưới quy mô lớn sẽ được thực hiện vào mùa thu năm 2017, sau đó sẽ được gây quỹ Chính cho quỹ hỗ trợ phi lợi nhuận, với mạng “đám mây mở” dự kiến ​​sẽ ra mắt vào đầu mùa hè năm 2018 .

Language