RequireJS与AngularJS的集成

Moe

最近还有好多朋友在看这篇文章,实际上开源社区已经有更成熟的解决方案了。

评论中6楼的朋友说的解决方案就很好,大家可以直接看评论了。

因为项目不兼容IE6\IE7了,所以在最新的VIP商城活动中,我引入了angularJS。因为我们之前的前端架构是通过requirejs来进行加载模块的,所以直接将angular引入是不科学的,所以通过requirejs的配置让angularJS可以正常运行。以下是配置的步骤:

环境需求

  • require.js

  • angular.js

  • angular-route.js

有了这仨文件,就可以进行下一步了,具体将文件放到哪个目录,可以跟项目的目录结构走,无所谓。

配置步骤

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

require.config({
    //配置angular的路径
    paths:{
        "angular":"path/to/angular", 
        "angular-route":"path/to/angular-route",
    },
    //这个配置是你在引入依赖的时候的包名
    shim:{
        "angular":{
            exports:"angular"
        },
        "angular-route":{
            exports:"angular-route"
        }
    }
})

配置地址的时候容易出错,这里需要些耐心。
下一步是最关键的一步了,我在弄的时候被绕懵了好几次,英文网站上的教程用的名词容易分不清,英文不好是硬伤。。。
我们平常在写angular的时候是这样写的:

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

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

可以看到,几乎所有的操作都是在app上进行的。那么,在使用requirejs的时候,我们通常是这样写模块的:

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

而两者结合起来理想中应该是这样的:

//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.js

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。

阅读 44.9k

Moe
望山的马
236 声望
7 粉丝
0 条评论
你知道吗?

236 声望
7 粉丝
宣传栏