AngularJS1.3一些技巧

前言

框架选择。在上一篇文章评论中,有人说angular1.3是个过时的东西,建议使用angular2。其实这种说法很像拿jQuery1.x和jQuery2.x做比较,新的版本当然会有优化优势的地方,但并不一定是最适合你项目的。当你项目必须支持IE6/7/8时,那又得使用jQuery1.x版本。所以不要以新不新去选择一个框架或者某个版本,而是看是不是适合的。当初用angular1.3是他比较成熟有配套的文档,而angular2的文档是不健全的,另外有一点是1.x与2.x的区别太大了,两者的用法没有继承性。更重要的是,目前的angular2只有Alpha版本(测试),并没有一个正式版本。

性能。有人说angular2的性能会比较好,我还没有用过,不做什么评论。但对于angular1.x,我确实是不放心它的性能的,作为PC Web我敢用angular,但在移动终端我不敢用,在我看来无论从框架体积或框架运行效率,在脆弱的移动端都是致命的。有一些基于angular做的Hybrid框架(例Ionic),希望使用过的人能告诉我它体验怎么样(性能上)。

 
一些技巧

这篇文章记录一些angular1.3的小技巧,angular2我会找个时间做个实践。

1. ng-repeat多个字段排序的写法

使用orderBy过滤器,第一个参数是一个数组,表示依次按数组中的属性值进行排序(若按第一项比较的值相等,再按第二项比较),第二个参数是正序还是倒序(默认是正序)。

ng-repeat="groupUser in groupUsers | orderBy:['isOwner','isAdmin']:true"
 
2. ng-include引入HTML片段

使用ng-include,第一个参数是页面的相对地址的字符串。应该注意,是一个字符串,不是ng-expression,所以不要忘了加单引号,否则会发现怎么都引不进这个HTML片段。

<div ng-include="'msgs.html'"></div>
 
3. ng-bind的$scope对象没有随着数据变化而变化

自己实现的ajax,获取数据后,设置到$scope上,view却没有更新。这其实就是angular双向数据的原因,angular不可预见的scope变化,是不会帮忙刷新view的(例$.ajax或setTimeout)。解决方法就是,数据设置到$scope上后,手动调$scope.$apply();。

PS:一些指令(例ng-click、ng-model)以及服务(例$timeout、$http)才会自动刷新view。

 
4. 移动触摸(Touch)事件

angular-touch模块提供了触摸的事件和其他手势ngSwipeLeft、ngSwipeRight。

 
5. ng-bind-html的内容无法正常的显示在页面中

使用ng-bind-html属性,该属性依赖于$sanitize,也就是需要引入angular-sanitize.js文件。但会发现ng-bind-html的内容无法正常的显示在页面中,这是因为某些标签会被angularJS认为是不安全的自动过滤掉,而为了保留这些表情就需要开启非安全模式。

<div ng-bind-html="article.content | trustHtml">
</div>
myApp.filter('trustHtml', function ($sce) {
return function (input) { return $sce.trustAsHtml(input);
}
});

其中$sce是angular自带的安全处理服务,$sce.trustAsHtml(input) 返回的是受信任的对象。

 
6.  如何划分一个module

我的想法是在关系比较密切(业务逻辑)的页面可以划为一个module,因为页面可能存在共用service或template或directive(controller不共用),而这些元件归属于同个module,我们就可以不同页面调用了。而不想关的页面可划分为另一个module,增加代码的清晰度。

 
7. 是否要把工具类弄成service

在弄工程之前,我会考虑到是否要将一些工具类封装成一个service(为了看起来代码统一),但我发觉是没有必要的,因为service是归属于某个模块的,而我们的工具类可能在不同模块都有使用,不归属于某个模块。把工具类当成一个jquery的库引入即可。

 
8. 配合RequireJS使用

angular没有异步加载模块的功能,所以使用配合RequireJS使用的效果还是不错的。在这里面有些异议的是对于模块定义的地方,是该把一个模块定义成RequireJS的模块还是angular的服务(可以依赖注入),我觉得还是功能归属的问题,如果是全局使用的工具服务,就定义成RequireJS模块,而如果是与模块密切相关的业务逻辑就使用服务。

PS:可在RequireJS的config加上urlArgs,可以避免缓存问题。

urlArgs: "bust=" +  (new Date()).getTime()  //可用来清理缓存,在部署到生产环境去掉。
 
9. iframe打开跨域URL时报错
<iframe width="100%" height="100%" ng-src="{{url}}"></iframe>

如果不做处理,上面的跨域URL是打不开的, 需要定义白名单。

myApp.config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
// Allow same origin resource loads.
'self',
// Allow loading from our assets domain. Notice the difference between * and **.
"https://link.bingosoft.net/**"]);
});
 
10. 使用其他Controller的scope的属性方法

先声明我并不清楚我的用法是否恰当。使用其他Controller的scope局限于其parent scope,而不是任何Controller的都可以访问。scope有个属性$parent, 通过这个属性可以找到某一层Controller的scope。

var parentScope = $scope.$parent.$parent.$parent;

PS:多少层$parent是我打印scope对象出来找的。

 
11. form表单的自动提交功能
在输入框点击回车时候,AngularJS会默认触发第一个button的click事件。
 
总结
这一篇是angular1.3的小技巧,希望有用。
 
本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。
上一篇:c语言小程序以及java生成注释文档方法


下一篇:HDU 2604 - Queuing