最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在ASP.NET MVC項目中使用RequireJS庫的用法示例

 更新時間:2016年02月15日 14:29:45   作者:P_Chou  
這篇文章主要介紹了在ASP.NET MVC項目中使用RequireJS的用法示例,文中主要講解了網(wǎng)站項目的一些基本目錄結(jié)構(gòu)思想,并給出了一個半自動壓縮的例子,的朋友可以參考下

RequireJS 是一個前端模塊化開發(fā)的流行工具,本身是一個Javascript的庫文件,即require.js 。
RequireJs的主要功能:

(1)實現(xiàn)js文件的異步加載,避免網(wǎng)頁失去響應(yīng);

(2)管理模塊之間的依賴性,便于代碼的編寫和維護。

前端模塊化開發(fā)現(xiàn)在有好多的工具,大體上分為兩類,一類是像dojo之類的高大全,dojo v1.8之后已經(jīng)內(nèi)置了模塊化開發(fā)組件;另一類是像require.js,sea.js 這種專心做模塊化開發(fā)的工具。

從模塊化劃分的規(guī)則來區(qū)分,主要分為AMD、CMD兩類,dojo、require.js 遵從前者,而sea.js 依循CMD規(guī)范。

require在單頁面應(yīng)用中能夠如魚得水,然而對于傳統(tǒng)的多頁面應(yīng)用,使用require多少會有些困惑和不方便。

本文講解如何在ASP.NET MVC的結(jié)構(gòu)中應(yīng)用require,并且給出了壓縮腳本,實現(xiàn)半自動化壓縮。

將js代碼分離
一般而言ASP.NET MVC的一個路由對應(yīng)一個視圖,視圖的文件結(jié)構(gòu)可能如下:


Views
 |--Shared
 |--_layout.cshtml
 |--Home
 |--Index.cshtml
 |--Blog
 |--Create.cshtml
 |--Edit.cshtml
 |--Detail.cshtml
 |--Index.cshtml

這里假設(shè)_layout.cshtml是所有頁面共享的。一般情況下,我們會在_layout中引用公共的js類庫,比如jQuery,bootstrap等,這樣的話其他的頁面就不需要對這些類庫再引用一遍,提高了編碼的效率。然而,不同的頁面終究會依賴不同的js,尤其是實現(xiàn)頁面本身功能的自定義的js,這樣我們不得不在其他頁面中再引用特殊的js,甚至將js直接寫在頁面中,例如下面的代碼經(jīng)常會出現(xiàn)在View中:

<script type="text/javascript">
 $(function(){...});
</script>

這樣會導(dǎo)致頁面比較混亂,而且頁面<script>標(biāo)簽中代碼不能被瀏覽器緩存,增加了頁面代碼的長度。更為重要的缺陷是,諸如jQuery之類的類庫會在加載到頁面后執(zhí)行匿名函數(shù),這需要一些時間,而如果有些頁面根本不需要jQuery的話,只要頁面把_layout作為布局頁面,那么jQuery的初始化代碼將不可避免的執(zhí)行,這是一種浪費。事實上,javascript的模塊化加載的思想就是為了解決這些問題的。

接下來我們來用require規(guī)劃我們的js,構(gòu)建諸如下面結(jié)構(gòu)的js目錄


js
|--app
 |--home.index.js
 |--blog.create.js
 |--blog.edit.js
 |--blog.detail.js
 |--blog.index.js
|--jquery.js
|--bootstrap.js
|--underscore.js
|--jquery.ui.js
|--jquery.customplugin.js
|--config.js
|--require.js

把公共的類庫級別的js模塊直接放在js目錄下,而把頁面級別的js放在一個app的子目錄下。注意,在app中,每個頁面一個js文件,這意味著我們需要把頁面各自的js提取出來,雖然這樣增加了結(jié)構(gòu)復(fù)雜度,但是避免了在頁面中隨手寫<script>標(biāo)簽的陋習(xí)。另外,在js目錄下的公共庫,除了第三方的庫,還包括自己開發(fā)的庫,還有一個叫config.js的文件,這個文件很關(guān)鍵,稍后會說到。

然后,我們可以刪除_layout中所有的js引用,并使用@RenderSection的命令要求子頁面提供js引用,_layout.cshtml:

<head>
...
@RenderSection("require_js_module", false)
...
</head>

這樣對js的需求就下放到每個view頁面中了,根據(jù)require的用法,我們需要在各個子View中引用require.js,并指定主模塊,而這些主模塊就是上面app目錄下的一個個js

@section require_js_module{
 <script src="@Url.Content("~/js/require.js")" data-main="@Url.Content("~/js/app/home.index.js")" ></script>
}

所有的js代碼都將寫到app下的js中,這樣規(guī)范了js,使得頁面更干凈,更為重要的是這些js還可以經(jīng)過壓縮,以及被瀏覽器緩存等,進一步提高執(zhí)行效率

公共的config
我們知道主模塊除了使用require方法外,經(jīng)常需要通過require.config來配置其他模塊的路徑,甚至需要shim,例如下面的代碼經(jīng)常會出現(xiàn)在主模塊的開頭:

require.config({
 paths: {
 "jquery": "lib/jquery.min",
 "underscore": "lib/underscore.min",
 "backbone": "lib/backbone.min"
 },
 shim: {
 'underscore':{
  exports: '_'
 },
 'backbone': {
  deps: ['underscore', 'jquery'],
  exports: 'Backbone'
 }
 }
});

對于單頁面應(yīng)用來說,主模塊往往只有一個,所以上面的代碼寫一遍也就OK了。但是,在多頁面的情況下,主模塊有多個,每個主模塊都要包含這樣的代碼,豈不是很不科學(xué)?于是,希望有一個統(tǒng)一配置的地方,但是應(yīng)該如何來寫呢?我們想到,將這些配置作為一個模塊config.js,讓其他的主模塊對這個模塊產(chǎn)生依賴就可以了,例如下面的config.js:
requirejs.config({
 paths: {
 "jquery": "/js/jquery.min",
 "bootstrap": "/js/bootstrap"
 },
 shim: {
 'bootstrap': {
  deps: ['jquery'],
  exports: "jQuery.fn.popover"
 }
 }
});

config.js的寫法沒有什么特別的,接下來只要在home.index.js中引用

require(['../config','jquery', 'bootstrap'], function () {
 //main module code here

});

不過這樣寫還是不對的,因為,被主模塊依賴的模塊(這里的config,jquery,bootstrap),在加載的時候,加載順序是不確定的,但是又需要config模塊在其他模塊之前加載,怎么辦呢?一個折衷的方案是修改home.index.js,成為如下代碼:

require(['../config'], function () {
 require(['home.index2']);
})
, define("home.index2", ['jquery', 'bootstrap'], function () {
 //main module code here
})

使用一個命名的模塊home.index2作為過渡,在主模塊中手動require,這樣可以保證config在主模塊執(zhí)行之前加載,也就使得home.index2在加載的時候已經(jīng)加載了config了。

壓縮
require提供一個壓縮工具,用于壓縮和合并js,詳情請移步至http://requirejs.org/docs/optimization.html。簡單的說,require提供一個叫r.js的文件,通過本地的node程序(Node.js),執(zhí)行這個r.js并傳入一些參數(shù),即可自動分析模塊互相之間的依賴,以達到合并和壓縮的目的。同樣的,這對于單頁面應(yīng)用來說是容易的,因為主模塊只有一個,但是對于多頁面又如何做呢?好在這個壓縮工具支持用一個配置文件來指導(dǎo)壓縮,這樣的話,我們可以編寫下面的配置腳本build.js:

var build = {
 appDir: '../js',
 baseUrl: '.',
 dir: '../js-built',
 mainConfigFile: '../js/config.js',
 modules: [
 //First set up the common build layer.
 {
  //module names are relative to baseUrl
  name: 'config',
  //List common dependencies here. Only need to list
  //top level dependencies, "include" will find
  //nested dependencies.
  include: ["bootstrap", "config","jquery"]
 },
 //Now set up a build layer for each page, but exclude
 //the common one. "exclude" will exclude nested
 //the nested, built dependencies from "common". Any
 //"exclude" that includes built modules should be
 //listed before the build layer that wants to exclude it.
 //"include" the appropriate "app/main*" module since by default
 //it will not get added to the build since it is loaded by a nested
 //require in the page*.js files.
 {
 name:"app/home.index",
 exclude:["config"]
 },
 {
 name:"app/blog.create",
 exclude:["config"]
 },
 ...
 ]
}

通過這個命令來執(zhí)行壓縮,壓縮的結(jié)果將被保存到j(luò)s-build目錄:

node.exe r.js -o build.js

build.js腳本實際上是一個js對象,我們將config加入公共模塊,而在各個主模塊中將其排除。這樣,所有的公共庫包括config將壓縮成一個js,而主模塊又不會包含多余的config。這樣可想而知,每個頁面在加載時最多只會下載兩個js,而且公共模塊的代碼會“按需執(zhí)行”。

執(zhí)行上面的腳本壓縮,需要安裝有node??梢栽趶倪@里下載。

自動腳本
但是,隨著主模塊的增加,需要隨時跟蹤和修改這個build文件,這也是很麻煩的。于是,筆者基于node.js開發(fā)了一個叫build-build.js的腳本,用來根據(jù)目錄結(jié)構(gòu)自動生成build.js:

fs = require('fs');
var target_build = process.argv[2];
//console.log(__filename);
var pwd = __dirname;
var js_path = pwd.substring(0,pwd.lastIndexOf('\\')) + '\\js';
console.log('js path : ' + js_path);
var app_path = js_path + '\\app';
console.log('js app path : ' +app_path);

var app_modules = [];
var global_modules = [];

//build json object
var build = {
 appDir: '../js',
 baseUrl: '.',
 dir: '../js-built',
 modules: [
 //First set up the common build layer.
 {
  //module names are relative to baseUrl
  name: 'config',
  //List common dependencies here. Only need to list
  //top level dependencies, "include" will find
  //nested dependencies.
  include: []
 }
 ]
}

fs.readdir(app_path,function (err,files) {
 // body...
 if (err) throw err;
 for(var i in files){
 //put module in app_modules
 var dotindex = files[i].lastIndexOf('.');
 if(dotindex >= 0){
  var extension = files[i].substring(dotindex+1,files[i].length);
  if(extension == 'js'){
  app_modules.push({
   name: 'app/' + files[i].substring(0,dotindex),
   exclude: ['config']
  });
  }
 }
 }

 for(var j in app_modules){
 build.modules.push(app_modules[j]);
 }
 
 fs.readdir(js_path,function (err,files){
 if (err) throw err;
 for(var i in files){
  //put module in app_modules
  var dotindex = files[i].lastIndexOf('.');
  if(dotindex >= 0){
  var extension = files[i].substring(dotindex+1,files[i].length);
  if(extension == 'js'){
   global_modules.push(files[i].substring(0,dotindex));
  }
  } 
 }

 build.modules[0].include = global_modules;
 //console.log(build);
 var t = pwd + '\\' + target_build;
 console.log(t);
 var fd = fs.openSync(t, 'w');
 fs.closeSync(fd);
 var json = JSON.stringify(build);
 fs.writeFileSync(t, json);
 });
});

這里的代碼并不復(fù)雜,主要是遍歷目錄,生成對象,最后將對象序列化為build.js。讀者可以自行閱讀并修改。最后,編寫一個bat,完成一鍵壓縮功能,build.bat:

@echo off
set PWD=%~p0
set PWD=%PWD:\=/%
cd "D:\node"
node.exe %PWD%build-build.js build.js
node.exe %PWD%r.js -o %PWD%build.js
cd %~dp0

這樣,我們就簡單實現(xiàn)了一個方便的多頁面require方案,最后項目目錄可能是這樣的:

Views
 |--Shared
 |--_layout.cshtml
 |--Home
 |--Index.cshtml
 |--Blog
 |--Create.cshtml
 |--Edit.cshtml
 |--Detail.cshtml
 |--Index.cshtml

build
|--build.js
|--r.js
|--build-build.js
|--build.bat

js
|--app
 |--home.index.js
 |--blog.create.js
 |--blog.edit.js
 |--blog.detail.js
 |--blog.index.js
|--jquery.js
|--bootstrap.js
|--underscore.js
|--jquery.ui.js
|--jquery.customplugin.js
|--config.js
|--require.js


相關(guān)文章

  • wx-charts 微信小程序圖表插件的具體使用

    wx-charts 微信小程序圖表插件的具體使用

    這篇文章主要介紹了wx-charts 微信小程序圖表插件的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Javascript實現(xiàn)檢測客戶端類型代碼封包

    Javascript實現(xiàn)檢測客戶端類型代碼封包

    在以前,總是以為使用用戶代理字符串檢測瀏覽器是那種類型就行了,這樣確實大錯特錯啊,下面就來說說如何通過js判斷出當(dāng)前瀏覽者使用的的設(shè)備類型呢
    2015-12-12
  • ES10 特性的完整指南小結(jié)

    ES10 特性的完整指南小結(jié)

    這篇文章主要介紹了ES10 特性的完整指南小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • JavaScript使用百度ECharts插件繪制餅圖操作示例

    JavaScript使用百度ECharts插件繪制餅圖操作示例

    這篇文章主要介紹了JavaScript使用百度ECharts插件繪制餅圖操作,結(jié)合實例形式分析了JavaScript使用百度ECharts插件繪制餅圖的原理、步驟及相關(guān)操作注意事項,需要的朋友可以參考下
    2019-11-11
  • from 表單提交返回值用post或者是get方法實現(xiàn)

    from 表單提交返回值用post或者是get方法實現(xiàn)

    from 表單提交的返回值可以用jquery的post或者是get方法去實現(xiàn),具體如下,感興趣的朋友可以參考下,希望對大家有所幫助
    2013-08-08
  • JS獲取checkbox的個數(shù)簡單實例

    JS獲取checkbox的個數(shù)簡單實例

    下面小編就為大家?guī)硪黄狫S獲取checkbox的個數(shù)簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • JavaScript版本迷局介紹

    JavaScript版本迷局介紹

    有人說喜歡一個人,沒必要了解她的過去,然而想讀懂一個人,卻需要了解她的過去。
    2011-01-01
  • 繪制微信小程序驗證碼功能的實例代碼

    繪制微信小程序驗證碼功能的實例代碼

    這篇文章主要介紹了繪制微信小程序驗證碼功能的實例代碼,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • 原生JavaScript制作計算器

    原生JavaScript制作計算器

    本文給大家匯總了2個原生JavaScript實現(xiàn)的計算器功能的代碼,一個簡單一個稍微復(fù)雜些,小伙伴們根據(jù)自己的需要來選擇吧
    2016-10-10
  • 如何利用JavaScript實現(xiàn)二叉搜索樹

    如何利用JavaScript實現(xiàn)二叉搜索樹

    這篇文章主要給大家介紹了關(guān)于如何利用JavaScript實現(xiàn)二叉搜索樹的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評論

宝兴县| 涞水县| 永寿县| 湟中县| 革吉县| 黑龙江省| 东港市| 洞口县| 五台县| 潢川县| 年辖:市辖区| 天柱县| 阳原县| 中超| 九龙城区| 青冈县| 潼南县| 延川县| 西昌市| 博爱县| 木兰县| 庄浪县| 阜新市| 策勒县| 积石山| 三江| 连南| 天等县| 本溪市| 略阳县| 新昌县| 双城市| 华阴市| 万安县| 宁化县| 淳安县| 探索| 延津县| 龙胜| 平舆县| 南开区|