Angular系列學(xué)習(xí)筆記(二)—— 基于gulp構(gòu)建Angular單頁面應(yīng)用

文章來源:小青年原創(chuàng)
發(fā)布時間:2017-4-1
關(guān)鍵詞:gulp涯雅,angular,angular-ui-router瘸爽,angular-material
轉(zhuǎn)載需標(biāo)注本文原始地址: http://zhaomenghuan.github.io/#!/blog/20170401

前言

構(gòu)建打包工具之前一直是使用 webpack(歪脖帕克您访,畢竟尤大推薦的工具),由于公司這邊是使用gulp剪决,為了和公司同步灵汪,私下還是要學(xué)習(xí)學(xué)習(xí)檀训,畢竟懂點萬一需要和老大交流也不至于說有啥問題,這篇文章將會以零基礎(chǔ)的角度去寫一下基于gulp搭建angular的工程享言,借這個機(jī)會順便重構(gòu)一下自己的博客峻凫。

gulp基礎(chǔ)入門

在開工之前確保自己已經(jīng)安裝了node環(huán)境,沒有安裝的自行安裝好node览露,安裝的時候默認(rèn)會安裝npm包管理器荧琼。安裝好了通過下列的命令檢查版本:

$ node -v
v7.5.0
$ npm -v
4.1.2

然后看看gulp的文檔和文章取取經(jīng)開始我們今天的工作:
node官網(wǎng)
npm官網(wǎng)
gulp中文網(wǎng)入門指南
Gulp開發(fā)教程(翻譯)

基本流程

創(chuàng)建package.json文件

新建一個文件夾開始,這里我以zhaomenghuan-blog肛循,然后然后命令行進(jìn)入項目目錄:

# 創(chuàng)建 package.json 文件铭腕,直接一路回車就好
npm init

這是在創(chuàng)建一個 package.json 文件,定義了這個項目所需要的各種模塊多糠,以及項目的配置信息(比如名稱累舷、版本、許可證等元數(shù)據(jù))夹孔。詳細(xì)介紹可以看阮一峰老師的這篇文章:package.json文件被盈。

安裝 gulp

全局安裝 gulp

npm install gulp -g

作為項目的開發(fā)依賴(devDependencies)安裝:

npm install gulp -D

這兩者的區(qū)別可以看看這篇文章:npm 常用命令詳解。執(zhí)行完這一步搭伤,目錄下就多了一個node_modules文件夾只怎,里面都是依賴的模塊。一般來說怜俐,我們可能會在其它項目中使用的工具身堡,如這里的gulp我們會先進(jìn)行全局按照,這樣會在本地有一個“倉庫”拍鲤,以后再用的時候直接下載到項目中豈可贴谎,避免每次不必要的下載等待。另外季稳,dependencies字段指定了項目運行所依賴的模塊擅这,devDependencies指定項目開發(fā)所需要的模塊。下載模塊的時候注意區(qū)分景鼠,分清楚依賴模塊的差異有助于我們后期優(yōu)化代碼仲翎,避免不必要的模塊引入到項目最終源碼中,造成代碼打包過大的問題铛漓。

創(chuàng)建 gulpfile.js 文件

在項目根目錄下創(chuàng)建一個名為 gulpfile.js 的文件:

var gulp = require('gulp');

gulp.task('default', function() {
  // 將你的默認(rèn)的任務(wù)代碼放在這
});

運行g(shù)ulp

gulp 或 gulp default

默認(rèn)的名為 default 的任務(wù)(task)將會被運行溯香,在這里,這個任務(wù)并未做任何事情浓恶。
想要單獨執(zhí)行特定的任務(wù)(task)逐哈,請輸入 gulp <task> <othertask>,例如在gulpfile.js里面添加如下代碼:

gulp.task('console', function() {
  console.log('hello gulp');
});

然后執(zhí)行gulp console就會輸入hello gulp问顷。

很顯然我們通過一些命令就可以執(zhí)行一下任務(wù)(task)昂秃,那么接下來的重點就是寫task相關(guān)的代碼禀梳。

gulpfile.js配置說明

上面的流程只是對gulp基本流程入門,但是對于gulp的強(qiáng)大功能還沒有直觀的感覺肠骆,下面我們通過常用的幾段配置看看配置的基本方法算途。需要說明的是,在使用插件之前我們都需要先安裝相關(guān)的模塊蚀腿。

創(chuàng)建具有熱更新的本地服務(wù) —— browser-sync

參考文檔擁有實時重載(live-reloading)和 CSS 注入的服務(wù)器這篇文章可知嘴瓤,使用 BrowserSync 和 gulp,你可以輕松地創(chuàng)建一個開發(fā)服務(wù)器莉钙,然后同一個 WiFi 中的任何設(shè)備都可以方便地訪問到廓脆。BrowserSync 同時集成了 live-reload 所以不需要另外做配置了。

安裝browser-sync模塊:

npm install browser-sync -D

可以通過gulp.watch監(jiān)聽文件變動并且自動刷新磁玉,如下:

var gulp = require('gulp');
var sass = require('gulp-ruby-sass');
var browserSync = require('browser-sync');
var reload = browserSync.reload;

gulp.task('sass', function() {
  return sass('scss/styles.scss')
    .pipe(gulp.dest('app/css'))
    .pipe(reload({ stream:true }));
});

// 監(jiān)視 Sass 文件的改動停忿,如果發(fā)生變更,運行 'sass' 任務(wù)蚊伞,并且重載文件
gulp.task('serve', ['sass'], function() {
  browserSync({
    server: {
      baseDir: 'app'
    }
  });

  gulp.watch('app/scss/*.scss', ['sass']);
});

Jade 模板文件轉(zhuǎn)換為 HTML 文件 —— gulp-jade

我們可以通過gulp-jade插件將jade模板轉(zhuǎn)成html文件席赂,如下:

var source = {
    templates: [
        { src: './src/index.jade', dist: './app/'},
        { src: './src/components/**/*.jade', dist: './app/components/'}
    ]
};

gulp.task('templates', function(){
    source.templates.forEach(function (item) {
        gulp.src(item.src)
            .pipe(jade({
                pretty: true
            }))
            .pipe(gulp.dest(item.dist))
            .pipe(reload({
                stream:true
             }));
    })
});

less 文件轉(zhuǎn)換成css文件 —— gulp-less

var gulp = require('gulp');
var less = require('gulp-less');             // 解析less
var minifycss = require('gulp-minify-css'); // 壓縮css
var uglify = require("gulp-uglify");         // 壓縮代碼
var concat = require("gulp-concat");         // 合并文件

var source = {
    styles: [
        './src/index.less',
        './src/components/**/*.less',
        './src/pages/**/*.less'
    ]
};

gulp.task('styles:source', function () {
    return gulp.src(source.styles) // 壓縮的文件
        .pipe(less())
        .pipe(minifycss()) // 執(zhí)行壓縮
        .pipe(concat('all.min.css'))
        .pipe(gulp.dest('./app/css/')) //輸出到指定目錄
        .pipe(reload({
            stream:true
        }));
});

壓縮圖片——gulp-imagemin

var gulp = require('gulp');
var imagemin = require('gulp-imagemin');     // 圖片壓縮
var source = {
    images: {
        src: './src/assets/images/*',
        dist: './app/assets/images'
    }
};

gulp.task('images', function () {
    gulp.src(source.images.src)
        .pipe(imagemin({
            optimizationLevel: 7
        }))
        .pipe(gulp.dest(source.images.dist));
});

從命令行傳遞參數(shù)設(shè)置項目開發(fā)模式

項目開發(fā)環(huán)境下我們經(jīng)常寫很多console.log調(diào)試程序,在上線的時候我們又不想手動刪除這些調(diào)試日志时迫,這時候我們可以通過插件來完成颅停。我們需要來配置兩個環(huán)境:

  • DEV 模式:在開發(fā)環(huán)境中,為了方便 debug掠拳,JavaScript 通常不做壓縮和混淆癞揉;
  • PROD 模式:上生產(chǎn)環(huán)境時,JavaScript 必須并合壓縮溺欧、混淆并成一個文件烧董,同時需要去除所有的 log 輸出語句。

我們可以通過命令行傳遞參數(shù)說明是什么模式胧奔,我們可以通過官方的例子從命令行傳遞參數(shù)學(xué)習(xí)如何使用。

// npm install --save-dev gulp gulp-if gulp-uglify minimist gulp-strip-debug

var gulp = require('gulp');
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');
var stripDebug = require('gulp-strip-debug');

var minimist = require('minimist');

var knownOptions = {
  string: 'env',
  default: { env: process.env.NODE_ENV || 'production' }
};

var options = minimist(process.argv.slice(2), knownOptions);

gulp.task('scripts', function() {
  return gulp.src('**/*.js')
    .pipe(gulpif(options.env === 'production', uglify())) // 僅在生產(chǎn)環(huán)境時候進(jìn)行壓縮
    .pipe(gulpif(options.env === 'production', stripDebug())) // 去掉console.log
    .pipe(gulp.dest('dist'));
});

默認(rèn)是development環(huán)境下预吆,如果想使用production環(huán)境可以通過如下命令運行 gulp:

$ gulp scripts --env development

每次在命令行輸入?yún)?shù)容易出錯龙填,為了方便我們可以將腳本寫在package.json中的scripts字段里面:

"scripts": {
    "dev": "gulp serve --env development",
    "build": "gulp serve --env production"
 },

然后執(zhí)行npm run devnpm run build命令就可以。

對于新手而言拐叉,可能理解這個流程更重要岩遗,這個流程跑通了,接下來無非就是看文檔入門了凤瘦,關(guān)于gulp后文不再一步步贅述宿礁,而是直接給出gulpfile.js的代碼。這里我們可以看出來gulp強(qiáng)大的功能得以實現(xiàn)蔬芥,依賴于各種方便的插件梆靖,與webpack中提供的各種loader十分類似控汉。可見要想完成各種負(fù)責(zé)的功能返吻,需要對常用插件進(jìn)行學(xué)習(xí)姑子,我們可以通過這里的例子學(xué)習(xí)相關(guān)的插件使用方法:gulp 技巧集

項目實戰(zhàn)

上面的例子對于我們搭建一個基礎(chǔ)工程足夠了测僵,下面我們通過一個實際例子來說明街佑。

項目結(jié)構(gòu):

├── node_modules // 打包過程中依賴的包
├── package.json // 包含各種所需模塊以及項目的配置信息
├── gulpfile.js // 打包配置文件
├── app // 打包之后最終部署到服務(wù)器上的文件(名稱自定義)
├── src  // 資源文件(名稱自定義)
   ├── components // 自定義全局組件
       ├── pageloading (如:頁面切換loading)
       ...
   ├── pages // 頁面路由組件
       ├── index
           ├── index.jade 默認(rèn)路由視圖
           ├── index.controller.js 默認(rèn)路由控制器
           └── index.config.js 默認(rèn)視圖路由配置
       ├── blog
       ···
   ├── assets // 靜態(tài)資源
       ├── images // 圖片資源
   ├── app.module.js // 全局模塊
   ├── index.jade // 入口視圖模板
   └── index.less // 入口視圖樣式
└── vendor.config.js // 依賴的庫配置文件(自定義)

本文工程地址:learn-angular => angular-material

ui-router使用指南

我們知道一個大型的單頁面應(yīng)用離不開路由,angular自帶了ngRouter捍靠,但是我們常用的是angularUI的ui-router沐旨,這是因為UI-Router有兩個重要的特性:

  • 多樣化視圖
  • 嵌入式視圖

ui-router支持多樣化視圖,并且每一個視圖都有自己相應(yīng)的控制榨婆,所以每個區(qū)塊都是封裝好磁携,可以復(fù)用到整個應(yīng)用程序需要的地方颜武,這就意味著我們可以實現(xiàn)視圖的復(fù)用和分治篙议。ui-router 引進(jìn)了狀態(tài)機(jī)設(shè)計模式这难,抽象高于傳統(tǒng)的路由。路由成了狀態(tài)剪个,URL就成了狀態(tài)的一個簡單屬性如暖。

對于ui-router最好的學(xué)習(xí)教程就是ui-router 官方wiki枷遂,我們下面會來講解一下新手常見的幾個問題侄榴。

下載:

npm install angular-ui-router -S

引入依賴:

var app = angular.module('app', ['ui.router']);

注意:是ui.router不是ui-router!

$stateProvider

處理路由狀態(tài)的服務(wù)醋旦,路由的狀態(tài)反映了該項在應(yīng)用程序中的位置钉凌,描述了在當(dāng)前狀態(tài)下UI是應(yīng)該怎么樣的,并且該做什么捂人。

依賴:$urlRouterProvider $urlMatcherFactoryProvider

decorator(name,func):通過內(nèi)部的$stateProvider以擴(kuò)展或者重寫狀態(tài)生成器御雕。可用于添加ui-router的自定義功能先慷,例如,基于狀態(tài)名稱推斷templateUrl咨察。
警告:因為生成器的函數(shù)執(zhí)行順序的不確定论熙,decorator不應(yīng)該相互依賴。
參數(shù):
name:需要修改的生成函數(shù)名稱摄狱。
func:負(fù)責(zé)修改生成器函數(shù)的函數(shù)脓诡。

state(name,stateConfig):注冊一個狀態(tài)无午,并給定其配置。
參數(shù):
name:狀態(tài)的名稱祝谚。
stateConfig:狀態(tài)配置對象宪迟。配置具有以下各項屬性:
template: string/function,html模板字符串交惯,或者一個返回html模板字符串的函數(shù)次泽;
templateUrl:string/function,模板路徑的字符串席爽,或者返回模板路徑字符串的函數(shù)意荤;
templateProvider:function,返回html模板字符串或模板路徑的服務(wù)只锻;
controller:string/function玖像,新注冊一個控制器函數(shù)或者一個已注冊的控制器的名稱字符串;
controllerProvider:function齐饮,返回控制器或者控制器名稱的服務(wù)捐寥;
controllerAs:string,控制器別名祖驱;
parent:string/object握恳,手動指定該狀態(tài)的父級;
resolve:object羹膳,將會被注入controller去執(zhí)行的函數(shù)睡互,<string,function>形式。
url:string陵像,當(dāng)前狀態(tài)的對應(yīng)url就珠;
views:object,視圖展示的配置醒颖,<string,object>形式妻怎;
abstract:boolean,一個永遠(yuǎn)不會被激活的抽象的狀態(tài)泞歉,但可以給其子級提供特性的繼承逼侦。默認(rèn)是true;
onEnter:function腰耙,當(dāng)進(jìn)入一個狀態(tài)后的回調(diào)函數(shù)榛丢;
onExit:function,當(dāng)退出一個狀態(tài)后的回調(diào)函數(shù)挺庞;
reloadOnSearch:boolean晰赞,如果為false,那么當(dāng)一個search/query參數(shù)改變時不會觸發(fā)相同的狀態(tài),用于當(dāng)你修改$location.search()的時候不想重新加載頁面掖鱼。默認(rèn)為true然走;
data:object,任意對象數(shù)據(jù)戏挡,用于自定義配置芍瑞。繼承父級狀態(tài)的data屬性。換句話說褐墅,通過原型繼承可以達(dá)到添加一個data數(shù)據(jù)從而整個樹結(jié)構(gòu)都能獲取到拆檬;
params:url里的參數(shù)值,通過它可以實現(xiàn)頁面間的參數(shù)傳遞掌栅。

$urlRouterProvider

$urlRouterProvider 在這里有兩個主要目的:一是建立一個默認(rèn)路由秩仆,用于管理未知的URL(統(tǒng)一跳轉(zhuǎn)到某處);二是監(jiān)聽瀏覽器地址欄URL的變化猾封,重定向到路由定義的狀態(tài)中澄耍。總之晌缘,$urlRouterProvider讓我們處理狀態(tài)機(jī)抽象的$stateProvider沒有檢測到的情況齐莲。

$urlRouterProvider負(fù)責(zé)監(jiān)聽$location.當(dāng)$location變化的時候,$urlRouterProvider開始在一個規(guī)則的列表中一個個的查找磷箕,直到找到匹配的值选酗。$urlRouterProvider用于在后端指定url的狀態(tài)配置。所有的url被編譯成UrlMatcher對象岳枷。
依賴: $urlMatcherFactoryProvider $locationProvider

deferIntercept(defer) :禁用(或啟用)延遲location變化的攔截芒填。
如果你想定制與URL同步的行為(例如,你需要保持當(dāng)前的URL去并且推遲一個變化),那么在配置的時候使用這個方法。
參數(shù):
defer:boolean渠缕,確定是禁止還是啟用該攔截慢蜓。

angular.module('app',['ui.router']).config(["$urlRouterProvider",function(){
     $urlRouterProvider.deferIntercept(defer); // defer = true/false 
}])

otherwise(rule):定義一個當(dāng)請求的路徑是無效路徑時跳轉(zhuǎn)的路徑谍椅。
參數(shù):
rule:你想重定向的url路徑或一個返回的網(wǎng)址路徑的規(guī)則函數(shù)。函數(shù)傳入兩個參數(shù):$injector和$location服務(wù),而且必須返回一個string的url。

angular.module('app',['ui.router']).config(["$urlRouterProvider",function(){
     $urlRouterProvider.otherwise(rule); // rule = 重定向的url規(guī)則
}])

**rule(rule): **定義使用$urlRouterProvider來匹配指定的URL的規(guī)則凯砍。
**參數(shù): **
rule:將$injector和$location作為arguments傳入的處理函數(shù)。用來返回一個string類型的url路徑拴竹。

angular.module('app',['ui.router']).config(["$urlRouterProvider",function($urlRouterProvider){
     $urlRouterProvider.rule(function ($injector, $location) {
        var path = $location.path(),
        normalized = path.toLowerCase();
        if (path !== normalized) {
           return normalized;
        }
    });
}])

when(what,handler):為給定的URL匹配注冊一個處理程序悟衩。
參數(shù):
what:需要重定向的傳入路徑。
handler:你想要重定向的路徑/處理程序栓拜。

  angular.module('Demo', ['ui.router']);
  .config(["$urlRouterProvider",function ($urlRouterProvider) {
    $urlRouterProvider.when($state.url, function ($match, $stateParams) {
      if ($state.$current.navigable !== state || !equalForKeys($match, $stateParams) {
       $state.transitionTo(state, $match, false);
      }
    });
  }]);

$urlRouter

依賴:$location $rootScope $injector $browser

href(urlMacther,params,options):一個生成URL的方法座泳,為給定的UrlMatcher返回編譯后的URL斑响,并且用提供的參數(shù)填充。
參數(shù):
urlMacther:用于當(dāng)作生成URL的模板的UrlMacther對象钳榨。
params:一個參數(shù)值的對象用來填補(bǔ)所需的匹配參數(shù)。
options:option對象纽门,absolute-boolean薛耻,如果為true,將會生成一個絕對地址赏陵。

  $bob = $urlRouter.href(new UrlMatcher("/about/:person"), {
    person: "bob"
  });
  // $bob == "/about/bob";

觸發(fā)更新:發(fā)生在地址欄URL變化時執(zhí)行相同的更新饼齿。

$state

$state服務(wù)負(fù)責(zé)代表狀態(tài)及提供狀態(tài)之間的轉(zhuǎn)換。它還提供你當(dāng)前的狀態(tài)及上一個狀態(tài)蝙搔。

依賴:$rootScope $q $view $injector $resolve $stateParams $urlRouter

get(stateOrName,context):返回任何指定的狀態(tài)或所有狀態(tài)的配置對象缕溉。
參數(shù):
stateOrName:如果提供此參數(shù),返回的是指定狀態(tài)的配置對象吃型;如果不提供此參數(shù)证鸥,則返回全部狀態(tài)的配置對象。
context:當(dāng)context是一個相對的參考狀態(tài)勤晚,狀態(tài)會在相關(guān)上下文中檢索枉层。

go(to,params,options):
參數(shù):
to:string,即將跳轉(zhuǎn)的狀態(tài)赐写。
params:object鸟蜡,跳轉(zhuǎn)所帶的參數(shù)。
options:object挺邀,可選配置對象揉忘。有 location(是否更新地址欄的url,或以什么字符串替換url)端铛,inherit(是否繼承當(dāng)前url的參數(shù))泣矛,relative(當(dāng)變化相對路徑:如"^,定義的狀態(tài)是相對的),notify(是否廣播$stateChangeStart和$stateChangeSuccess事件)沦补,reload(是否重新載入)乳蓄。

$state.go('contact.detail');

href(stateOeName,params,options):一個URL生成方法,返回為給定的狀態(tài)填充指定的參數(shù)編譯后的鏈接夕膀。
參數(shù):
stateOeName:string虚倒,你想要生成的url的狀態(tài)或者狀態(tài)對象。
params:object产舞,一個用于填充狀態(tài)需要的參數(shù)的對象魂奥。
options:可選配置對象。有l(wèi)ossy(當(dāng)?shù)谝粋€參數(shù)url未被提供時是否繼承導(dǎo)航的url進(jìn)行構(gòu)建href),inherit(是否繼承當(dāng)前url的參數(shù)),relative(當(dāng)變化相對路徑:如"^,定義的狀態(tài)是相對的),absolute(是否生成絕對url)易猫。

$state.href("about.person", { person: "bob" })

include(stateOrName,params,options):一個確定當(dāng)前有效的狀態(tài)是不是與stateOrName平級的還是其子狀態(tài)耻煤。
參數(shù):
stateOeName:string,部分名稱,相對名稱哈蝇,或者通過當(dāng)前狀態(tài)進(jìn)行全局模式查找棺妓。
params:object,一個參數(shù)對象炮赦。
options:可選配置對象怜跑。有relative。

is(stateOrName,params,options):與$state.include相似吠勘,只是這個針對的是全名性芬。參數(shù)性質(zhì)同上。

reload(state):重新載入當(dāng)前狀態(tài)的方法剧防。
參數(shù):
state:一個狀態(tài)名稱或者狀態(tài)對象植锉。

$state.reload('contact.detail');

transitionTo(to,toParams,options):過渡到一個新狀態(tài)的方法。
參數(shù):
to:狀態(tài)名稱峭拘。
toParams:將會發(fā)送到下一個狀態(tài)的參數(shù)俊庇。
options:可選參數(shù)。有l(wèi)ocation鸡挠,inherit暇赤,relative,notify宵凌,reload鞋囊。

$state.transitionTo($state.current, $stateParams, { 
    reload: true, inherit: false, notify: true
});

current:獲取當(dāng)前路由

$stateChangeError:路由狀態(tài)變化發(fā)生錯誤時觸發(fā)的事件。
參數(shù):
event瞎惫,toState溜腐,toParams,fromState瓜喇,fromParams挺益,error。

$stateChangeStart:路由狀態(tài)變化發(fā)生前觸發(fā)的事件乘寒。
參數(shù):event望众,toState,toParams伞辛,fromState烂翰,fromParams。

$stateChangeSuccess:路由狀態(tài)變化正確時觸發(fā)的事件蚤氏。
參數(shù):event甘耿,toState,toParams竿滨,fromState佳恬,fromParams捏境。

$stateNotFound:路由狀態(tài)沒找到的時候觸發(fā)的事件。
參數(shù):event毁葱,unfoundState垫言,fromState,fromParams倾剿。

三種常用的方式激活路由狀態(tài)

  • $state.go():優(yōu)先級較高的便利方式
  • ui-sref:點擊包含此指令跳轉(zhuǎn)
  • url:url導(dǎo)航

ui-sref:一種將鏈接(<a>標(biāo)簽)綁定到一個狀態(tài)的指令骏掀。點擊該鏈接將觸發(fā)一個可以帶有可選參數(shù)的狀態(tài)轉(zhuǎn)換。ui-sref此指令必須綁定到<a>標(biāo)簽柱告,如果該路由有對應(yīng)的關(guān)聯(lián)URL,其通過$state.href()自動生成和更新href屬性笑陈。

<a ui-sref="blog" ui-sref-active="active">博客</a>
<a ui-sref="blog({id: pageId})">博客-2017</a>

ui-sref-active="active" 該路由激活际度,則對應(yīng)增加active樣式名稱,ui-sref-opts 傳遞參數(shù)涵妥。

html5模式 or Hashbang

$location服務(wù)有兩種用來控制地址欄URL格式的配置:Hashbang模式(默認(rèn))和HTML5模式(使用HTML5歷史API)乖菱。應(yīng)用會使用兩種模式中相同的API,并且$location服務(wù)會使用需要的URL片段和瀏覽器API來幫助改變URL或者進(jìn)行歷史管理蓬网。

html5模式 or Hashbang
對比 Hashbang模式 HTML5模式
配置 默認(rèn) { html5Mode: true }
URL格式 所有瀏覽器都支持 hashbang URLs在高級瀏覽器中使用regular URLs窒所,低級瀏覽器使用hashbang URLs
<a href=""> 鏈接重寫
需要服務(wù)器端配置

Hashbang模式(默認(rèn)mode)

使用這個模式的話,$location會在所有瀏覽器中使用Hashbang URLs帆锋。

$locationProvider.html5mode = false;
$locationProvider.hashPrefix = '!';

支持網(wǎng)絡(luò)爬蟲

你需要添加特別的meta標(biāo)記在你的文檔的頭部才能支持對你的AJAX應(yīng)用的索引吵取。

<meta name="fragment" content="!" />

這能讓網(wǎng)絡(luò)爬蟲請求帶有escaped_fragment形式的參數(shù)鏈接,這樣你就能識別爬蟲并且返回一個HTML的快照了锯厢。

HTML5模式

在HTML5模式中皮官,$location服務(wù)的讀寫器和瀏覽器的URL地址通過HTML5歷史API交互,這使你能用regular URL path并且搜索各組成部分实辑,和hashbang是等效的捺氢。 如果瀏覽器不支持HTML5 歷史API, $location服務(wù)會自動回退成使用hashbang URLs剪撬。你就不用擔(dān)心瀏覽器的支持性了摄乒。$location服務(wù)總是會用最好的選擇。

在低級瀏覽器中使用了regular URL -> 重定向成hashbang URL
在現(xiàn)代瀏覽器中打開了一個hashbang URL -> 重寫成regular URL

 $locationProvider.html5mode = true;

服務(wù)器端:使用這種模式需要開啟服務(wù)器端的URL重寫功能残黑,基本上你需要重寫所有指向你應(yīng)用的鏈接(如index.html)馍佑。

相對鏈接:記住要檢查所有的相對連接、圖片梨水、腳本等挤茄。你必須指定你主頁面的base url(<base href="/my-base">),或者你使用絕對路徑也行冰木,因為相對路徑會結(jié)合文檔的初始絕對路徑轉(zhuǎn)換成絕對路徑穷劈。文檔初始路徑通常和應(yīng)用的根路徑不一樣笼恰。

參考

gulp 技巧集
ui-router wiki
UI-Router:為什么開發(fā)者都不喜歡Angular.js內(nèi)置的路由
AngularJs ui-router 路由的簡單介紹
AngularJS開發(fā)指南27:使用$location

關(guān)注打賞

博客:http://zhaomenghuan.github.io
github:https://github.com/zhaomenghuan
segmentfault:https://segmentfault.com/u/zhaomenghuan

贊賞
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市歇终,隨后出現(xiàn)的幾起案子社证,更是在濱河造成了極大的恐慌,老刑警劉巖评凝,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件追葡,死亡現(xiàn)場離奇詭異,居然都是意外死亡奕短,警方通過查閱死者的電腦和手機(jī)宜肉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翎碑,“玉大人谬返,你說我怎么就攤上這事∪砧荆” “怎么了遣铝?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長莉擒。 經(jīng)常有香客問我酿炸,道長,這世上最難降的妖魔是什么涨冀? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任填硕,我火速辦了婚禮,結(jié)果婚禮上鹿鳖,老公的妹妹穿的比我還像新娘廷支。我一直安慰自己,他們只是感情好栓辜,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布恋拍。 她就那樣靜靜地躺著,像睡著了一般藕甩。 火紅的嫁衣襯著肌膚如雪施敢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天狭莱,我揣著相機(jī)與錄音僵娃,去河邊找鬼。 笑死腋妙,一個胖子當(dāng)著我的面吹牛默怨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骤素,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼匙睹,長吁一口氣:“原來是場噩夢啊……” “哼愚屁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起痕檬,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤霎槐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后梦谜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丘跌,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年唁桩,在試婚紗的時候發(fā)現(xiàn)自己被綠了闭树。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡荒澡,死狀恐怖报辱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仰猖,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布奈籽,位于F島的核電站饥侵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏衣屏。R本人自食惡果不足惜躏升,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望狼忱。 院中可真熱鬧膨疏,春花似錦、人聲如沸钻弄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窘俺。三九已至饲帅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瘤泪,已是汗流浹背灶泵。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留对途,地道東北人赦邻。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像实檀,于是被迫代替她去往敵國和親惶洲。 傳聞我的和親對象是個殘疾皇子按声,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容