Saturday, September 2, 2017

Angular 1: Tạo App Hoàn Chỉnh P5 - Cách Tạo Directive

phần 4 ta đã hoàn thành xong cách phân quyền cho từng view, nay ta tiếp tục với cơ bản cách tạo một directive, và nhận event từ bên ngoài.

1. Tạo directive
Tạo file ng-products.html và ng-products.js trong thư mục {angular1}/app/modules/ng-product như sau.
ng-products.html
<div class="ng-my-product">
 <h3 ng-bind="title"></h3>
 <a href="" ng-click="onBack()">go back</a>
 <div ng-repeat="product in products">
  <label ng-bind="product.name"></label>
  <label ng-bind="product.price + 'đ'"></label>
  <a href="" ng-click="showPrice({price: product.price})">show price call back</a>
  <a href="" ng-click="showProduct({product: product})">show detail</a>
  <hr/>
 </div>

 <div ng-transclude></div>
</div>
Ở trên ta có dùng một directive của angular là ng-transclude, mục dích là ta sẽ pass content trong directive vào ngày vị trí ta đặt ng-transclude.
ng-products.js
(function(){
 "use strict";
 angular.module("Directive.MyProduct",[])
  .directive("myproduct", [function(){
   return {
    restrict: "E", // A(attribute), E(element), C(class), M(comment)
    templateUrl: "app/modules/ng-products/ng-products.html",
    scope: { // without scope, we use scope from controller that embbed this directive
           products: '=', // =products
           title: '@',
           onBack: "&",
           showPrice: "&",
           showProduct: "&"
       },
       transclude: true,
       controller: ["$scope", function($scope){
        console.log("run me in controller");
       }],
       link: function(scope, element, attrs, ctrl) {
        console.log(scope);
        console.log(element);
        console.log(attrs);
        console.log(ctrl);
       }
   }
  }]);
})();
Ở trên ta có định nghĩa cách biến và callback function sau.
products(=): directive nhận vào một list sản phẩm.
title(@): tiêu để của directive, mọi thứ truyền vào param này đều được xem là chuỗi.
onBack, showPrice, showProduct(&): những param này sẽ nhận vào callback function.
transclude: true: ta cẩn phải phải báo để có thể truyền nội dung của directive vào ng-transclude

Tiếp theo ta import nó vào trong index.html và đăng ký ở mainCtrl
index.html
<body ng-controller="AppCtrl">
 ...
 <!-- directive -->
 <script src="app/modules/ng-products/ng-products.js"></script>
</body>
main.ctrl.js
angular.module("MyCtrl",[
 ...
 "Directive.MyProduct",
 ...
 ])
2. Dùng Directive ng-products
Ta dùng nó ở trang san-pham-list.html như sau
<div class="san-pham-list-com">
 ...
 <myproduct title="Sản Phẩm Chi Tiết" products="products" on-back="onBack()" show-price="showPrice(price)" show-product="showProduct(product)">
  <label>embed some html into directive
 </myproduct>
</div>
Ở trên ta nội dung của directive cụ thể là label sẽ đặt ở ngay vị trí mà ta đặt ng-transclude.
Trong san-pham-list.ctrl.js ta định nghĩa một số biến và function cần thiết cho directive
(function(){
 "use strict";
 angular.module("User.SanPhamList.Ctrl",[])
  .controller("ListSanPhamCtrl", ["$scope", function($scope){
   $scope.products = [
    {
     name: "Dầu Gội",
     price: 30000
    },
    {
     name: "Bột Giặc",
     price: 40000
    },
    {
     name: "Kem Đánh Răng",
     price: 10000
    }
   ];

   $scope.onBack = function() {
    console.log("go back only no param");
   }

   $scope.showPrice = function(priceParam) {
    console.log("call back show priceParam " + priceParam);
   }

   $scope.showProduct = function(product) {
    console.log("product detail");
    console.log(product);
   }
  }]);
})();
Ở trên controller ta định nghĩa một danh sách sản phẩm, và một số function, và việc còn lại là pass những function này vào directive như thế nào.
Bạn có thể thấy trong ng-products.html ta có 3 event chính sau
scope: {
 ...
 onBack: "&",
 showPrice: "&",
 showProduct: "&"
}
ng-click="onBack()"
ng-click="showPrice({price: product.price})"
ng-click="showProduct({product: product})"
Tương ứng ta pass function từ parent controller và directive như sau
<myproduct on-back="onBack()" />
<myproduct show-price="showPrice(price)" /> // price param phải giống như trong event click {price: product.price}
<myproduct show-product="showProduct(product)" /> // tương tự product param cũng phải giống như {product: product}
3. Khi ta vào trang san-pham ta sẽ thấy kết quả như sau
Khi ta click vào go back ta được
Khi ta click vào link show price call back ta được
Còn khi ta click vào show detail ta được object product
4. Tải source code ở đây
https://drive.google.com/open?id=0B-JvPy4-xKqkYi00YzNyQkRkWk0

No comments:

Post a Comment