RequireJS與AngularJS的集成

最近還有好多朋友在看這篇文章,實際上開源社區已經有更成熟的解決方案了。

評論中6樓的朋友說的解決方案就很好,你們能夠直接看評論了。

由於項目不兼容IE6\IE7了,因此在最新的VIP商城活動中,我引入了angularJS。由於咱們以前的前端架構是經過requirejs來進行加載模塊的,因此直接將angular引入是不科學的,因此經過requirejs的配置讓angularJS能夠正常運行。如下是配置的步驟:javascript

環境需求

  • require.js前端

  • angular.jsjava

  • angular-route.jsjquery

有了這仨文件,就能夠進行下一步了,具體將文件放到哪一個目錄,能夠跟項目的目錄結構走,無所謂。angularjs

配置步驟

首先要配置require.js的入口文件main.jsbootstrap

require.config({
    //配置angular的路徑
    paths:{
        "angular":"path/to/angular", 
        "angular-route":"path/to/angular-route",
    },
    //這個配置是你在引入依賴的時候的包名
    shim:{
        "angular":{
            exports:"angular"
        },
        "angular-route":{
            exports:"angular-route"
        }
    }
})

配置地址的時候容易出錯,這裏須要些耐心。
下一步是最關鍵的一步了,我在弄的時候被繞懵了好幾回,英文網站上的教程用的名詞容易分不清,英文很差是硬傷。。。
咱們日常在寫angular的時候是這樣寫的:api

var app = angular.module("xxx",["xxx"]);

app.controller("foo",function($scope){});
app.directive(...)

能夠看到,幾乎全部的操做都是在app上進行的。那麼,在使用requirejs的時候,咱們一般是這樣寫模塊的:架構

define(["jquery"],function($){})

而二者結合起來理想中應該是這樣的:app

//ctrl.js
define(['app'],function(app){
    app.controller("mainController",function($scope){
        ...
    })
})

//dirct.js
define(['app'],function(app){
   app.directive("xxx",function(scope){
        ...
    })
})

能夠看到,咱們在編寫controller和directive(或者service等等)的時候,都須要將方法做用在app上,那麼這個app是什麼的呢,其實能夠想到,就是angular.module("xxxapp",[])
那麼,如何讓全部的模塊都能引入angular.module("xxxapp",[])呢,咱們新建一個app.jsrequirejs

define(["angular","angular-route"],function(angular){
    return angular.module("xxxapp",['ngRoute']);
})

這樣,咱們在引入app.js的時候,就能夠拿到這個angular module了。
這裏須要注意如下幾點:

  • angular-route這個模塊沒有繼承在angular.js裏,因此咱們要單獨的引入,還有好比angular-animate這種文件也是須要單獨引用的。

  • angular.module("xxxapp",['ngRoute']);在這裏面,須要依賴ngRoute模塊,若是不引用會報錯,我沒有深究其緣由。

當這些步驟都作完以後,你會發現,這個程序仍是跑步起來。因此咱們還有最後一步。在啓動一個angular程序的時候,須要把全部使用angularjs編寫的模塊都加載到頁面中,要否則確定會報錯。。因此,咱們須要一個angular的加載模塊。能夠叫Bootstrap什麼的。

//angular-bootstrap.js
require(["angular"],["angular-route"],["app"],["xx.controller"].....,function(angular){
    angular.bootstrap(document,["you module's name"]);
})

angular.bootstrap方法是angular自帶的,顧名思義,若是手工去調用,就是啓動一個angular app的意思。具體看文檔

這樣,在你的頁面中或者入口JS裏require("angular-bootstrap"),就能夠運行angular程序了!揍是這麼折騰!沒錯!


4月30日更新:

  1. 如上配置完以後,頁面的加載會有閃爍,因而將模板中的{{xxx}}都改爲了ng-bind的形式。改完了以後從頁面渲染完到angular將數據填充完畢的那幾百毫秒仍是會閃一下。因而我想出了個hack,就是如今body或者某父標籤上加一個class這個class是負責visibility:hidden的。等到angular把數據填充完畢,再用jQuery把那個class remove掉,這樣就不會有閃爍了,進來先是空白的,而後一會兒出來,也比較符合日常的用戶習慣。

  2. 還有就是有的時候刷新會報module方法不存在,是由於angular-route文件沒有成功加載,很莫名其妙的問題,因此解決辦法也很hack,就是把angular-module.js的文件複製到angular的文件中,這樣在Main.js和其餘js文件中,就能夠把angular-route的依賴刪掉了,試了一下,果真OK。

相關文章
相關標籤/搜索