Angular-UI-Router 學習筆記

路由 Route

我在 慕課網 學習 AngularJSjavascript

爲何用 Route

  • AJAX 請求不會留下 History 記錄html

  • 用戶沒法直接經過 URL 進入應用中的指定頁面(保存書籤、連接分享給朋友)前端

  • AJAX 對 SEO 是個災難java

    var bookStoreApp = angular.module('bookStoreApp', [
        'ngRoute', 
        'ngAnimate', 
        'bookStoreCtrls', 
        'bookStoreFilters',
        'bookStoreServices', 
        'bookStoreDirectives'
    ]);
    
    bookStoreApp.config(
    
        // 路由機制
        function($routeProvider) {
            $routeProvider.when('/hello', {
                templateUrl: 'tpls/hello.html',
                controller: 'HelloCtrl'
            }).when('/list/:bookId', {
                templateUrl: 'tpls/bookList.html',
                constoller: 'BookListCtrl'
            }).otherwise({
                redirectTo: '/hello'
            });
        }
    );

嵌套 View (Nested Routing for AngularJS)

AngularUI-Router AngularUI

<div ui-view></div>

前端路由的基本原理

  • 哈希 #
  • HTML5 中新的 history API
  • 路由的核心是給應用定義 "狀態"
  • 使用路由機制會影響到應用的總體編碼方式(需預先定義好狀態)
  • 考慮兼容性問題與 "優雅降級"

Angular-UI-Router

ui-sref 指令連接到特定狀態

<a ui-sref="home">Home</a>
<a ui-sref="about">About</a>
<a ui-sref="contacts.list">Contacts</a>

$state.includes 返回 true / false

以上方法爲查看當前狀態是否在某父狀態內,好比 $state.includes('contacts') 返回 true / falsegit

<!-- 包含在 /contacts 狀態內部,即其做爲 parant state -->
<li ng-class="{active: $state.includes('contacts')}">
    <a ui-serif="contacts.list">Contacts</a>
</li>

ui-sref-active 查看當前激活狀態並設置 Class

<li ui-sref-active="active"><a ui-sref="about">About</a></li>

包含模塊

angular.module('uiRouter', ['ui.router']);

方便得到當前狀態的方法,綁到根做用域

app.run(['$rootScope', '$state', '$stateParams',
    function($rootScope, $state, $stateParams) {
        $rootScope.$state = $state;
        $rootScope.$stateParams = $stateParams;
    }
]);

路由重定向 $urlRouterProvider

app.config(['$stateProvider', '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider) {
        $urlRouterProvider
            // 錯誤的路由重定向
            .when('/c?id', '/contacts/:id')
            .when('/user/:id', '/contacts/:id')
            .otherwise('/');
    }
]);

狀態配置

$stateProvider.
    state('about', {
        url: '/about',
        template: '<h1>Welcome to UI-Router Demo</h1>',

        // optional below
        templateProvider: ['$timeout',
            function($timeout) {
                return $timeout(function() {
                    return '<p class="lead">UI-Router Resource</p>' +
                            '<p>The second line</p>'
                }, 100);
            }
        ],

        templateUrl: 'about.html',

        templateUrl: function() {
            return 'about.html';
        },

        controller: 'UIRouterCtrl',

        // below is a state controller picked from UI-Router official sample
        controller: ['$scope', '$state', 'contacts', 'utils',
            function ($scope, $state, contacts, utils) {
                $scope.contacts = contacts;

                $scope.goToRandom = function () {
                    var randId = utils.newRandomKey($scope.contacts, 'id', $state.params.contactId);

                    $state.go('contacts.details', { contactId: randId });
                }
            }
        ]
    });

嵌套配置 Configure

JavaScript Codes

Parent Router
$stateProvider.
    .state('contacts', {

        // abstract: true 代表此狀態不能被顯性激活,只能被子狀態隱性激活
        abstract: true,
        url: '/contacts',
        templateUrl: 'contacts.html',

        // resolve 被使用來處理異步數據調用,如下是返回一個 promise -> contacts.all()
        resolve: {
            contacts: ['contacts',
                function(contacts) {
                    // 如下方法被放在 contacts.service.js 中,以 factory 存在
                    return contacts.all();
                }
            ]
        },

        // below is a state controller picked from UI-Router official sample
        controller: ['$scope', '$state', 'contacts', 'utils',
            function ($scope, $state, contacts, utils) {
                $scope.contacts = contacts;

                $scope.goToRandom = function () {
                    var randId = utils.newRandomKey($scope.contacts, 'id', $state.params.contactId);

                    $state.go('contacts.details', { contactId: randId });
                }
            }
        ]
    })
Children Router (Nested Router)
$stateProvider
    .state('contacts.list', {
        url: '',
        templateUrl: 'contacts.list.html'
    })

    .state('contacts.detail', {
        url: '/{contactId:[0-9]{1,4}}',

        // view 用在該狀態下有多個 ui-view 的狀況,能夠對不一樣的 ui-view 使用特定的 template, controller, resolve data
        // 絕對 view 使用 '@' 符號來區別,好比 'foo@bar' 代表名爲 'foo' 的 ui-view 使用了 'bar' 狀態的模板(template),相對 view 則無
        views: {
            // 無名 view
            '': {
                templateUrl: 'contacts.detail.html',
                controller: ['$scope', '$stateParams', 'utils',
                    function ($scope, $stateParams, utils) {
                        $scope.contact = utils.findById($scope.contacts, $stateParams.contactId);
                    }
                ]
            },

            // for "ui-view='hint'"
            'hint@': {
                template: 'This is contacts.defail populating the "hint" ui-view'
            },
            
            // for "ui-view='menuTip'"
            'menuTip': {
                templateProvider: ['$stateParams',
                    function($stateParams) {
                        return '<hr><small class="muted">Contact ID: ' + $stateParams.contactId + '</small>';
                    }
                ]
            }
        }
    })

HTML Codes

<h2>All Contacts</h2>
<ul>
  <li ng-repeat="contact in contacts">
    <a ui-sref="contacts.detail({contactId:contact.id})">{{contact.name}}</a>
  </li>
</ul>
相關文章
相關標籤/搜索