最近还有好多朋友在看这篇文章,实际上开源社区已经有更成熟的解决方案了。
评论中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日更新:
如上配置完之后,页面的加载会有闪烁,于是将模板中的{{xxx}}都改成了ng-bind的形式。改完了之后从页面渲染完到angular将数据填充完毕的那几百毫秒还是会闪一下。于是我想出了个hack,就是现在body或者某父标签上加一个class这个class是负责
visibility:hidden
的。等到angular把数据填充完毕,再用jQuery把那个class remove掉,这样就不会有闪烁了,进来先是空白的,然后一下子出来,也比较符合平常的用户习惯。还有就是有的时候刷新会报module方法不存在,是因为angular-route文件没有成功加载,很莫名其妙的问题,所以解决办法也很hack,就是把angular-module.js的文件复制到angular的文件中,这样在Main.js和其他js文件中,就可以把angular-route的依赖删掉了,试了一下,果然OK。