Thứ Năm, 5 tháng 1, 2017

Xóa bỏ thẻ hash # trên đường dẫn URL

Mặc định, AngularJS sẽ điều hướng ứng dụng phía client sử dụng 1 thẻ hash # hoặc #!
Nó có dạng như thế này:
  • http://example.com/
  • http://example.com/#/about
  • http://example.com/#/contact
Rõ ràng trông như thế thì không được đẹp và có cảm giác không thân thiện với người dùng. Và chúng ta mong muốn xóa bỏ thẻ hash # này đi, và trông nó xinh xắn như thế này.
  • http://example.com/
  • http://example.com/about
  • http://example.com/contact
Để làm được việc như vậy, thì có 2 việc bạn cần làm đó là:
  1. Cấu hình $locationProvider
  2. Chỉ định URL mặc định cơ sở, bằng cách sử dụng thẻ <base>
Chú ý: URL mặc định ở bước 2 là một chỉ dẫn để AngularJS lấy làm cơ sở cho các đường link tương đối khác hoạt động đúng như mong đợi. Thẻ <base> chỉ được sử dụng một lần trong tài liệu HTML và PHẢI nằm trong thẻ <head>
$location Service
Trong AngularJS, $location service sẽ tự động thu thập các thông tin về địa chỉ URL của trình duyệt tại thời điểm hiện tại, nó sẽ phục vụ cho mục đích điều hướng của ứng dụng.
Bạn hãy tìm hiểu thêm về Service này tại đây, để xem nó cung cấp những gì cho bạn sử dụng 🙂 AngularJS $location

Cấu hình $locationProvider

Chúng ta cần phải cấu hình locationProvider để bất chế độ html5Mode cho phép chúng ta loại bỏ được thẻ hash (đây là mode cho phép sử dụng HTML5 History API của trình duyệt).
Như vậy, đoạn cấu hình điều hướng ứng dụng AngularJS được cài đặt như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
angular.module('myApp', [])
     
    .config(function($routeProvider, $locationProvider) {
        $routeProvider
            .when('/', {
                templateUrl : 'partials/home.html',
                controller : mainController
            })
            .when('/about', {
                templateUrl : 'partials/about.html',
                controller : mainController
            })
            .when('/contact', {
                templateUrl : 'partials/contact.html',
                controller : mainController
            })
            .otherwise({
                templateUrl : 'partials/404.html'
            });
     
        // use the HTML5 History API
        $locationProvider.html5Mode(true);
    });
Chú ý: HTML5 History API là một chuẩn để thao tác với lịch sử duyệt Web của Trình duyệt. Điều này cho phép AngularJS thay đổi URL của trang web SPA mà không phải Refresh lại trang. Các bạn có thể tìm hiểu thêm về bài hướng dẫn tại HTML5 History API

Chỉ định URL cơ sở

Để cho các liên kết tương đối trong ứng dụng hoạt động được, bạn cần chỉ định URL cơ sở bằng cách sử dụng thẻ <base> trong thẻ <head> của tài liệu HTML.
1
2
3
4
5
6
7
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <base href="/">
</head>
Một lần nữa, sau khi xóa bỏ thẻ hash xong ứng dụng của bạn giờ đây đã trông thân thiện hơn dựa trên AngularJS. Chúc bạn thành công! 🙂

Vấn đề có thể xảy ra, liên quan đến Server

Đến đây thì bạn đã có thể tùy biến thẻ base là / hoặc theo một domain các ứng dụng con, ví dụ <base href="/app1"> hoặc <base href="/app2">
Nhưng có thể có 1 số vấn đề hoặc lỗi sau đây xảy ra, đó là: Người dùng nhập trực tiếp đường link ứng dụng, hoặc refresh lại trang Web, ví dụ: http://example.com/about thì sẽ nhận được một thông báo lỗi 404 Not Found. Vì sao vậy ? Bạn có nhận thấy vấn đề không ?
Đó là do với đường link đó, khi trình duyệt gửi yêu cầu thì Server không hiểu và không tìm được resource /about, và quyết định trả về mã lỗi 404. Ứng dụng của chúng ta đã thiết kế điều hướng ở phía client bởi AngularJS rồi, thế nên khi không tìm được Resource thì Server nên trả về trang mặc định, ví dụ: index.html và để AngularJS quyết định việc hiển thị.
Ví dụ cấu hình sử dụng: Nginx
1
2
3
4
5
location / {
    root /my_angular_app/dist;
    try_files $uri $uri/ /index.html =404;
    add_header Access-Control-Allow-Origin *;
}
Ví dụ cấu hình sử dụng: Sails.js
1
2
3
4
5
module.exports.routes = {
    '/*': {
    view: 'index'
  }
};
Ví dụ cấu hình sử dụng: Express.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var express = require("express");
var path = require("path");
var app = express();
// Provide all routes here, this is for Home page.
app.get("/*"function(req, res) {
  res.sendFile(path.join(__dirname+'/index.html'));
});
// Listen to this Port
app.listen(3000, function() {
  console.log("Live at Port 3000");
});



Sưu tầm http://how.vndemy.com/js/angular/1472-angularjs-xoa-bo-hash-tren-duong-dan-url/

Thứ Tư, 4 tháng 1, 2017

Xây dựng cấu trúc thư mục cho ứng dụng AngularJS.

Khi bắt đầu xây dựng một ứng dụng AngularJS, có thể bạn không biết chính xác cách thức tổ chức các files, hoặc thậm chí là không biết mình cần những files nào. Trong bài viết này, tôi sẽ trình bày về cách tạo ra một ứng dụng bằng AngularJS và cách tổ chức cấu trúc thư mục với các ứng dụng ở các mức độ khác nhau.

Tạo ứng dụng đơn giản

Bạn chỉ cần 1 thư mục gồm 1 file index.html và 1 file app.js như sau:
app/
----index.html
----app.js
Trong file index.html, chúng ta cần gọi đến thư viện angularjs, file app.js và sử dụng các chỉ thị lệnh (directive) ng- đã được xây dựng sẵn cho ứng dụng angularjs. Bạn có thể tìm hiểu thêm trong tài liệu về AngularJS.
Hiện nay, việc sử dụng cấu trúc thư mục ứng dụng như thế nào là tốt nhất đang là vấn đề được quan tâm đối với một số nhà phát triển. Dĩ nhiên, không có mô hình nào được coi là hoàn hảo. Tôi sẽ trình bày các xu hướng cấu trúc thư mục đang được áp dụng hiện nay.

Typical Struture

Trong đa số các tutorial hướng dẫn về angularjs, cấu trúc thư mục được áp dụng như sau:
app/
----- controllers/
---------- mainController.js
---------- otherController.js
----- directives/
---------- mainDirective.js
---------- otherDirective.js
----- services/
---------- userService.js
---------- itemService.js
----- js/
---------- bootstrap.js
---------- jquery.js
----- app.js
assets/
----- img/      // Images and icons for your app
----- css/      // All styles and style related files (SCSS or LESS files)
----- js/       // JavaScript files written for your app that are not for angular
----- libs/     // Third-party libraries such as jQuery, Moment, Underscore, etc.
views/
----- mainView.html
----- otherView.html
----- index.html
Đây là cấu trúc đặc trưng thường thấy. Với cấu trúc này, chúng ta tách riêng từng loại file vào chung một thư mục, controllers có thư mục riêng cho controllers, directives có thư mục riêng cho directives, …. Nó khá giống với cách tổ chức của các MVC framework. Cấu trúc này phù hợp với các ví dụ và các ứng dụng nhỏ và cho những người mới bắt đầu tìm hiểu AngularJS vì nó giúp cho người đọc dễ hình dung và có thể khái quát hóa các khái niệm đang được nghiên cứu.

Nguyên tắc LIFT

John Papa đưa ra nguyên tắc khi cấu trúc thư mục rất hữu ích trong bài viết Angular App Structuring Guidelines đó là LIFT (Locating - Indenty - Flat - T-DRY).
  1. Locating: dễ dàng định vị được file cần tìm.
  2. Indentify: xác định được đoạn code chúng ta cần tìm một cách nhanh chóng.
  3. Flat: làm phẳng cấu trúc nhất có thể.
  4. T-DRY: cố gắng để không lặp lại những gì đã làm (Try to Don’t Repeat Yourself).

Lựa chọn cấu trúc khi ứng dụng lớn dần lên

Có nhiều cách để tổ chức thư mục. Ở đây, chúng ta tập trung vào 2 cách cấu trúc: By Type (theo loại file) và By Feature (theo đặc tính).




Cấu trúc by type

Với cấu trúc by type theo cột bên trái, sẽ phù hợp với các ứng dụng nhỏ. Khi các chức năng nhiều dần lên, giả sử chúng ta có nhiều hơn 10 controllers, directives, views, và chúng ta muốn thay đổi một nội dung naò đó. Khi đó, chúng ta vẫn có thể xác định được các files cần thiết trong từng thư mục riêng biệt nhưng sẽ khó khăn trong việc tìm thấy file đó ngay lập tức trong cả mớ file controller, directive, views, …. Khi đó, chúng ta chuyển sang cấu trúc theo tính năng (by feature).

Cấu trúc by feature

Với cấu trúc by feature (cột bên phải hình), chúng ta sẽ nhóm các files có liên quan đến một tính năng nào đó vào trong cùng một thư mục. Nó sẽ bao gồm các file view, directive , controller, service cho tính năng đó. Chúng ta có thể coi mỗi một folder theo feature là một mô hình MVC thu nhỏ. Với cách này, khi cần thay đổi một tính năng nào đó, chúng ta có thể dễ dàng và nhanh chóng xác định được vị trí và đoạn code chúng ta cần làm việc, nó giúp chúng rút ngắn được thời gian phát triển của dự án.

Kết luận

Có rất nhiều cách để tổ chức cấu trúc thư mục ứng dụng và không có cách nào là hoàn hảo. Chúng ta dựa trên quy mô ứng dụng để chọn một cấu trúc phù hợp với ứng dụng của mình. Các bạn cũng có thể tự tạo ra cấu trúc của riêng mình ;). Và điều quan trọng nhất vẫn là cấu trúc phải rõ ràng và chúng ta có thể dễ dàng và nhanh chóng xác định được cái mà chúng ta cần làm.

Thứ Năm, 29 tháng 12, 2016

OPEN GRAPH LÀ GÌ VÀ TẠI SAO TA CẦN NÓ?

Open Graph Protocol biến website của bạn trở thành một phần của mạng xã hội. Nó bao gồm các thẻ để bạn định nghĩa dữ liệu có cấu trúc giúp cho việc chia sẽ dữ liệu giữa trang web với các trang mạng xã hội dễ dàng hơn.  Ví dụ : khi người dùng facebook click vào nút like trên trang web của bạn,  thì trang web của bạn sẽ xuất hiện trên trang facebook có nhân của người đó.
Cách thực hiện như sau:
Bạn đặt thẻ <meta>  trong head của trang web. Có bốn thuộc tính yêu cầu cho mỗi trang:
  • og:title – Tiêu đề trang web. Ví dụ, “Open Graph là gì và tại sao ta cần nó?”.
  • og:type – Loại đối tượng, ví dụ, “video.movie”. Tùy loại đối tượng mà ta cần khai báo thêm một số thuộc tính khác. Chẳng hạn, hình ảnh thì cần khai báo thêm kích thước.
  • og:image – Đường dẫn tới ảnh thumbnail sẽ hiển thị (khi bạn like, share…).
  • og:url – Đường dẫn tới trang web, ví dụ, http://www.imdb.com/title/ tt0117500/ 
<html prefix="og: http://ogp.me/ns#">
<head>
<title>The Rock (1996)</title>
<meta property="og:title" content="The Rock" />
<meta property="og:type" content="video.movie" />
<meta property="og:url" content="http://www.imdb.com/title/tt0117500/" />
<meta property="og:image" content="http://ia.media-imdb.com/images/rock.jpg" />
...
</head>
...
</html>
Ngoài ra còn có nhiều thuộc tính khác, chi tiết tại http://ogp.me/

Thứ Năm, 22 tháng 12, 2016

Cách khai báo một Controller trong Anguarjs

Có 2 cách khai báo một Controller trong Angularjs:
Cách 1:
angular.module("productPageApp").controller("ProductPageController",function($scope){
            $scope.isQuickViewMode=4;
});
angular.module("productPageApp").directive("productPage", function($filter){
            var directive = {
            restrict: "E",
            templateUrl: "product-page.directive.html",
            controller: "ProductPageController",
        };
        return directive;
});
Trong trang product-page.directive.html
<div>
{{ isQuickViewMode }}
</div>

Cách 2:
angular.module("productPageApp").controller("ProductPageController", ProductPageController);
    ProductPageController.$inject = [ "$log", "$scope", "$filter", "$window"];
    function ProductPageController($log, $scope, $filter, $window) {
        var productPageCtrl = this;
        productPageCtrl.isQuickViewMode = "1";
    }
angular.module("productPageApp").directive("productPage", function($filter){
            var directive = {
            restrict: "E",
            templateUrl: "product-page.directive.html",
            controller: "ProductPageController",
            controllerAs: "productPageCtrl",
        };
        return directive;
});
Trong trang product-page.directive.html
<div>
{{ productPageCtrl.isQuickViewMode }}

</div>