Scope là một khái niệm quan trọng bậc nhất còn Directive lại là một trong những chức năng mạnh mẽ nhất trong AngularJS. Nếu không hiểu về Scope cũng như không biết cách tận dụng sức mạnh Directive (để DRY Code Front-End) thì không thể xem như Dev đó biết AngularJS rồi. Nếu bạn quan tâm đến AngularJS cũng như Directive trong AngularJS, bạn có thể tìm đọc qua các tài liệu đầy đủ như AngularJS Directive Guide hay qua Ebook này. Trong bài viết này, mình chỉ viết ngắn gọn về một khía cạnh nhỏ: Scope của Directive nhằm mục đích tra cứu và tham khảo của bản thân sau này.
Tài liệu về Scope cho các bạn chưa quen với Scope: Understanding Scopes.
Scope trong Directive
Mọi Directive đều có scope gắn liền với nó. Directive sử dụng scope để access data bên trong template, link, controller. Chúng ta có thể khai báo Scope trong phần định nghĩa Directive theo một trong các giá trị sau:
-
Scope: false - Directive sẽ sử dụng chung Parent Scope. Mọi thay đổi của Scope bên trong Directive đều được phản ảnh trên Parent Scope của nó.
-
Scope: true - Directive sẽ tạo một Scope mới của riêng nó và kế thừa lại Parent Scope của nó. Mọi thay đổi của Directive Scope sẽ không làm ảnh hưởng đến giá trị của Parent Scope, tuy nhiên thay đổi bên Parent Scope lại được phản ảnh bên trong Directive Scope.
- Scope: {} - Directive sẽ tạo một Scope cô lập (isolated) mới, đây là phần thú vị nhất trong Scope Directive. Một Scope bị cô lập mới, tách hẳn ra khỏi Parent Scope và không kế thừa giá trị nào từ Parent Scope. Bạn phải khai báo cụ thể nếu muốn truyền giá trị từ Parent Scope đến Directive Isolated Scope. Isolated Scope giúp cho Directive có thể tái sử dụng ở nhiều nơi khác nhau và không phụ thuộc vào Parent Scope chứa nó. Truyền giá trị cho một Isolated Scope bằng cách dùng một trong các Prefix sau:
- @ (Text binding / one-way binding): Chỉ truyền Text hoặc giá trị của một model (Angular theo mô hình MVVM) vào Directive (chứ không phải bản thân model). Do vậy, khi sử dụng @ với model, phải thêm cặp dấu {{ và }} để lấy giá trị của model đó. @ thường được sử dụng để khởi tạo giá trị ban đầu cho Directive Scope.
- = (Direct model binding / two-way binding): tại một binding 2 chiều giữa Directive Scope và Parent Scope, do vậy, nó luôn expect được truyền vào một model, điều đó có nghĩa là bạn không thể truyền một expression như là một giá trị vào thuộc tính được map bởi dấu =. = thường được sử dụng để chia sẻ dữ liệu và giao tiếp giữa Directive Scope và Parent Scope.
- & (Behaviour Binding / Method Binding): Là một method binding nên đúng với tên gọi của nó, & được dùng để truyền một method từ Parent Scope vào Directive Scope. Nó rất hữu dụng khi bạn muốn invoke một method của Parent Scope từ bên trong Directive Scope.
- Nếu muốn tìm hiểu thêm về Prefixes trong Directive Isolated Scope, mời bạn đọc thêm tại đây.
Phân biệt compile - controller - link function trong Directive
Một câu hỏi khác cũng khá thú vị khi làm việc với Directive trong AngularJS và nảy ra khi mình đang viết bài này, đó là :
Phân biệt compile function, link function, controller function trong AngularJS Directive??
Nhiều lúc mình dùng loạn cả lên, bình thường thì dùng controller, khi thích thì dùng link function. (Hiếm khi dùng compile function)
Mình tìm được một bài khá chi tiết của một Dev người Việt trên Quora. Và đây là đáp án - TLDR:
Here is the rules for those functions
-
compile should be used when you need modify directive template, like add new expression, append another directive inside this directive… You’ll need to use compile function to do those jobs.
-
controller is used when you need to share or manipulate $scope data. Or when you want directive interactive with each other.
-
link is the function which used when you need to attach event handler, modify DOM.
Khác biệt cơ bản là Compile sẽ chạy trước tiên, trước khi DOM compile hoàn tất. Controller chạy sau Compile nhưng cũng trước khi DOM hoàn tất nhưng controller không can thiệp được vào DOM. Link chạy sau khi compile và có thể modify DOM.
Một quy ước chung của Angular: Write business logic in controller and DOM manipulation in link.
- Một bài viết khá chi tiết về compile & controller & link (pre-link, post-link) và Do / Don’t Do của chúng trên StackOverflow: Tham khảo
Phiên bản AngularJS 2.0 cũng sắp chính thức ra mắt, mình vẫn chưa tìm hiểu nên không biết có thay đổi gì nhiều liên quan đến scope không. Phải tìm hiểu mới được, hẹn các bạn ở một dịp khác.