Sự khác biệt giữa các chức năng 'bộ điều khiển', 'liên kết' và 'biên dịch' khi xác định một lệnh


393

Một số nơi dường như sử dụng chức năng điều khiển cho logic chỉ thị và những nơi khác sử dụng liên kết. Ví dụ về các tab trên trang chủ góc sử dụng bộ điều khiển cho một và liên kết cho một lệnh khác. Sự khác biệt giữa hai là gì?


2
Có lẽ một tổng quan toàn diện hơn về các chức năng chỉ thị: Chỉ thị góc - khi nào nên sử dụng biên dịch, bộ điều khiển, liên kết trước và sau liên kết .
Izhaki

Câu trả lời:


635

Tôi sẽ mở rộng câu hỏi của bạn một chút và cũng bao gồm chức năng biên dịch.

  • hàm biên dịch - sử dụng cho thao tác DOM mẫu (nghĩa là thao tác của phần tử tEuity = mẫu), do đó các thao tác áp dụng cho tất cả các bản sao DOM của mẫu được liên kết với lệnh. (Nếu bạn cũng cần một hàm liên kết (hoặc các hàm liên kết trước và sau) và bạn đã xác định hàm biên dịch, hàm biên dịch phải trả về (các) hàm liên kết vì 'link'thuộc tính bị bỏ qua nếu 'compile'thuộc tính được xác định.)

  • chức năng liên kết - thường được sử dụng để đăng ký các cuộc gọi lại người nghe (nghĩa là các $watchbiểu thức trên phạm vi) cũng như cập nhật DOM (nghĩa là thao tác của iEuity = thành phần cá thể riêng lẻ). Nó được thực hiện sau khi mẫu đã được nhân bản. Ví dụ, bên trong một <li ng-repeat...>, chức năng liên kết được thực thi sau khi <li>mẫu (tEuity) đã được sao chép (thành một iEuity) cho thành <li>phần cụ thể đó . A $watchcho phép một lệnh được thông báo về các thay đổi thuộc tính phạm vi (một phạm vi được liên kết với từng phiên bản), cho phép lệnh này hiển thị giá trị phiên bản cập nhật cho DOM.

  • chức năng điều khiển - phải được sử dụng khi một lệnh khác cần tương tác với lệnh này. Ví dụ, trên trang chủ AngularJS, chỉ thị khung cần thêm chính nó vào phạm vi được duy trì bởi chỉ thị tab, do đó chỉ thị tab cần xác định phương thức điều khiển (nghĩ API) mà chỉ thị khung có thể truy cập / gọi.

    Để được giải thích sâu hơn về các chỉ thị tab và khung và tại sao chỉ thị tab tạo một chức năng trên bộ điều khiển của nó bằng cách sử dụng this(chứ không phải trên $scope), vui lòng xem 'this' vs $ scope trong bộ điều khiển AngularJS .

Nói chung, bạn có thể đặt các phương thức $watches, v.v. vào chức năng điều khiển hoặc liên kết của lệnh. Bộ điều khiển sẽ chạy đầu tiên, mà đôi khi vấn đề (xem này fiddle mà các bản ghi khi các chức năng ctrl và liên kết chạy với hai chỉ thị lồng nhau). Như Josh đã đề cập trong một bình luận , bạn có thể muốn đặt các hàm thao tác phạm vi bên trong một bộ điều khiển chỉ để thống nhất với phần còn lại của khung.


131
Lời giải thích này phải có trong các tài liệu chính của AngularJS hoặc ít nhất là một tài liệu tham khảo về nó
Dogoku

7
Đây là một câu trả lời thông tin nhưng tôi nghĩ rằng nó rất khó đọc. Có lẽ nhiều dấu câu và câu nhỏ hơn có thể giúp đỡ. Nói chung tôi rất biết ơn câu trả lời.
Marty Cortez

Trình biên dịch $ bỏ qua thuộc tính 'link' với sự có mặt của thuộc tính 'compile'. Nhưng còn sự hiện diện của thuộc tính 'bộ điều khiển' thì sao? Liệu 'trình điều khiển' có khiến trình biên dịch $ bỏ qua một trong hai hoặc cả hai thuộc tính 'liên kết' và 'biên dịch' không? Có thể và / hoặc nên sử dụng 'biên dịch' cùng với 'bộ điều khiển' không?
Carl G

1
@CarlG, sự hiện diện của thuộc tính bộ điều khiển không ảnh hưởng đến trình biên dịch $ liên quan đến liên kết và biên dịch. Bạn có thể sử dụng biên dịch và bộ điều khiển.
Mark Rajcok

1
"Trình nghe DOM" KHÔNG "(nghĩa là $ biểu thức đồng hồ trên phạm vi)". Một người lắng nghe DOM cho các sự kiện như mouseover, sự kiện khác về phạm vi thay đổi thuộc tính. Sự khác biệt lớn.
Dmitri Zaitsev

56

Để bổ sung cho câu trả lời của Mark, hàm biên dịch không có quyền truy cập vào phạm vi, nhưng hàm liên kết thì có.

Tôi thực sự khuyên bạn nên video này; Viết Chỉ thị của Misko Hevery (cha đẻ của AngularJS), nơi ông mô tả sự khác biệt và một số kỹ thuật. (Sự khác biệt giữa chức năng biên dịch và chức năng liên kết tại 14:41 đánh dấu trong video ).


3
+1 cho liên kết đến video. Nó rất nhiều thông tin.
Rob Ki ERIC


35
  1. chạy mã trước khi biên dịch: sử dụng bộ điều khiển
  2. chạy mã sau khi biên dịch: sử dụng Liên kết

Quy ước góc: viết logic nghiệp vụ trong bộ điều khiển và thao tác DOM trong liên kết.

Ngoài ra, bạn có thể gọi một hàm điều khiển từ chức năng liên kết của một lệnh khác. Ví dụ: bạn có 3 lệnh tùy chỉnh

<animal>
<panther>
<leopard></leopard>
</panther> 
</animal>

và bạn muốn truy cập động vật từ bên trong chỉ thị "con báo".

http://egghead.io/lessons/angularjs-directive-c truyền thông sẽ hữu ích để biết về giao tiếp giữa các chỉ thị


18
"chạy mã trước khi biên dịch: sử dụng bộ điều khiển". Điều này là không chính xác; compilesẽ luôn luôn được thực hiện trước controller .
Izhaki

Bạn sẽ không (ít nhất là không theo cách đơn giản) có thể truy cập động vật từ chỉ thị báo của bạn. Các chỉ thị con có thể truy cập các phương thức của bộ điều khiển trong một lệnh cha mẹ, nhưng các chỉ thị anh chị em (như trong ví dụ trên) không thể gọi các bộ điều khiển của nhau.
Benjamin White

2
Là báo thực sự là một loại con báo? Ngoài ra, trên một ghi chú bên cạnh ... Bạn có thể có một liên kết - VÀ - bộ điều khiển trong một lệnh không?
Cody

1
có báo / báo đốm là báo đốm. và có, bạn có liên kết và bộ điều khiển trong chỉ thị.
Rahul

1
Từ hướng dẫn dành cho nhà phát triển Angular: "Thực tiễn tốt nhất: sử dụng bộ điều khiển khi bạn muốn hiển thị API cho các chỉ thị khác. Nếu không, hãy sử dụng liên kết."
Martin van Driel 04/11/2015

6

hàm biên dịch -

  1. được gọi trước bộ điều khiển và chức năng liên kết.
  2. Trong hàm biên dịch, bạn có DOM mẫu gốc để bạn có thể thay đổi DOM gốc trước khi AngularJS tạo một thể hiện của nó và trước khi một phạm vi được tạo
  3. ng-repeat là ví dụ hoàn hảo - cú pháp ban đầu là phần tử mẫu, các phần tử lặp lại trong HTML là các thể hiện
  4. Có thể có nhiều phiên bản phần tử và chỉ một phần tử mẫu
  5. Phạm vi chưa có sẵn
  6. Hàm biên dịch có thể trả về hàm và đối tượng
  7. trả về một hàm (post-link) - tương đương với việc đăng ký hàm liên kết thông qua thuộc tính liên kết của đối tượng config khi hàm biên dịch trống.
  8. trả về một đối tượng có (các) chức năng được đăng ký thông qua các thuộc tính trước và sau - cho phép bạn kiểm soát khi nào một chức năng liên kết sẽ được gọi trong giai đoạn liên kết. Xem thông tin về các chức năng liên kết trước và sau liên kết dưới đây.

cú pháp

function compile(tElement, tAttrs, transclude) { ... }

bộ điều khiển

  1. được gọi sau hàm biên dịch
  2. phạm vi có sẵn ở đây
  3. có thể được truy cập bởi các chỉ thị khác (xem thuộc tính yêu cầu)

liên kết trước

  1. Chức năng liên kết chịu trách nhiệm đăng ký người nghe DOM cũng như cập nhật DOM. Nó được thực hiện sau khi mẫu đã được nhân bản. Đây là nơi mà hầu hết các logic chỉ thị sẽ được đặt.

  2. Bạn có thể cập nhật dom trong bộ điều khiển bằng angular.element nhưng điều này không được khuyến khích vì phần tử được cung cấp trong hàm liên kết

  3. Hàm pre-link được sử dụng để triển khai logic chạy khi js góc đã biên dịch các phần tử con nhưng trước khi bất kỳ liên kết bài của phần tử con nào được gọi

liên kết

  1. Chỉ thị có chức năng liên kết, góc xử lý chức năng như một liên kết bài

  2. bài đăng sẽ được thực thi sau khi biên dịch, bộ điều khiển và funciton liên kết trước, vì vậy đó là lý do tại sao đây được coi là nơi an toàn và mặc định nhất để thêm logic chỉ thị của bạn

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.