1、如何设计友好的REST APIcss
1.使用uuid代替idhtml
2.URI参数定义由/users/age/20/60改成/users?minAge=20&&maxAge=60express
3.四大method,GET是安全的,HEAD也安全,POST/PUT/DELETE是不安全的数组
4.让GET的实现不要改变资源状态,由于GET的攻击手段要比针对其余METHOD的多一点浏览器
方法 | 含义 | 安全 | 幂等 |
GET | 读取资源列表或指定资源详情 | 是 | 是 |
HEAD | 获取资源概况 | 是 | 是 |
POST | 建立新资源 | 否 | 否 |
PUT | 更新指定资源 | 否 | 是 |
DELETE | 删除指定资源 | 否 | 是 |
幂等的意义在于:它能够安全地自动重试刚才的操做,而不用担忧破坏业务逻辑安全
5.分页的参数模式,推荐使用“起始位置offset+条数size”,通常使用GET请求资源,结果返回数组形式,总条数放在响应头中(用HEAD方法去取,可定时刷新)session
2、语法糖controller asapp
推荐写法:ide
angular.module('app').controller('DemoController', function() { var vm = this; vm.title = 'angular'; return vm; })
3、双向绑定和watchers函数函数
compileProvider服务能够用来关闭调试信息(调试类:ng-binding、ng-scope、ng-isolate-scope等)
app.config(function($compileProvider) {
//disable debug info
$compileProvider.debugInfoEnabled(false);
})
4、one-time绑定
若是数据是静态数据,则在绑定的时候为了不$watch产生致使性能降低,选择单次绑定: $watch在第一次实行是必要的,但以后由于不改变数据因此没有必要$watch。
单次表达式在第一次$digest完成后,将再也不计算(检测属性的变化),以“::”做为前缀的表达式为one-time绑定
<ul> <li ng-repeat="session in sessions"> <div class="info"> {{::session.name}} </div> </li> </ul>
注意:目前测试one-time不适用于动态数据
5、滚屏加载(针对大数据集显示)
ngInfiniteScroll开源组件实现滚屏加载
6、老是用ng-model做为输出
有ngModel的地方均可以使用ng-change事件
7、用打包代替动态加载
8、angular-hint
定位angular中常见的错误问题
9、拦截器
angular的拦截器(interceptors)可以实现对全部Ajax请求拦截和切入,分为四个切入点:
1.AJax请求Request以前切入
2.AJax请求Request错误时切入
3.AJax请求响应成功时切入
4.AJax请求响应失败时切入
$provide.factory('myHttpInterceptor', function($q) { return { //可选方法 'request': function(config) { //成功以后作一些事情 return config; }, 'requestError': function(rejection) { //出错以后作一些事情 return $q.reject(rejection); }, 'response': function(response) { //成功以后作一些事情 return response; }, 'responseError': function(rejection) { //出错以后作一些事情 return $q.reject(rejection); } }; });
$httpProvider.interceptors.push('myHttpInterceptor');
在实际项目中,设置token的代码应该放在登录成功或者是首页Controller加载的resolve等位置,这须要根据项目具体状况而定。
建议使用factory定义拦截器
10、装饰器
1.用在对第三方服务的扩展
angular.module('com.ngnice.app').factory('foo', function() { return { name: 'Angular' }; }); //利用Angular的装饰器来装饰foo服务;返回被修改后的代理对象 angular.module('com.ngnice.app').config(function($provide) { $provide.decorator('foo', function($delegate) { $delegate.greet = function() { return 'Hello, '+this.name; }; return $delegate; }); }); angular.module('com.ngnice.app').controller('DemoCtrl', function(foo) { var vm = this; console.log(foo.greet()); return vm; });
//输出:Hello, Angular
2.装饰器能够作到对服务进行通讯处理,如日志记录、访问控制、性能测试等
注意:除了constant的其余Provider服务:Value、Factory、Service、Provider定义的服务均可以被装饰器所装饰。costant是不可变的,它在定义的时候就已经肯定了服务实例,并不存在运行时的$get函数。
11、Ajax请求
$resource是基于$http之上,专门为简化Restful结构风格而设计的,适用面比$http更窄一些。
12、ng-cloak闪烁指令
Angular官方文档推荐咱们将Angular脚本引入在head中,或者在head中额外引入Angular.css样式文件,这样才能更早隐藏ngCloak节点,防止Angular表达式出现闪烁。
若是要兼容低版本IE(IE7)则要加上ngCloak样式属性,由于IE7浏览器不支持像“[ng-cloak]”这类CSS属性选择器:
<div ng-cloak class="ng-cloak">{{hello angular express on IE7}}</div>
compile是在angular开始解析指令的时候执行的
十3、directive
transclude:true属性的做用:让经过ng-trasclude透传过来的模板能够访问外部做用域,而不是内部做用域,即便定义了独立scope。
angular.module('com.ngnice.app').controller('TabSetComponentCtrl', function($scope) { var vm = $scope.vm = {}; vm.type = 'tabs'; }); angular.module('com.ngnice.app').directive('tabSet', function() { return { restrict: 'E', scope: {}, transclude: true, replace: true, template: '<ul ng-transclude class="nav nav-{{vm.type}}"></ul>', controller: 'TabSetComponentCtrl' }; }); document.createElement('tab-set');
模板中ng-transclude以外的部分只能访问当前指令的做用域,而透传过来的模板只能访问指令的外部做用域。
十4、ng-if-start/ng-if-end和ng-repeat-start/ng-repeat-end
<ul> <li ng-if-start="visibel">1</li> <li>2</li> <li ng-if-end>3</li> <li>4</li> </ul>
指定做用范围横跨多个平级元素。
十5、如何实现动态加载的HTML双向绑定
$compile服务实现这一功能。
<body ng-controller="DemoController as demo"> <dy-compile html="{{demo.html}}"></dy-compile> <button ng-click="demo.change();">改变</button> </body>
angular.module('com.ngnice.app').derective("dyCompile", ['$compile', function($compile) { return { replace: true, restricet: 'EA', link: function(scope, elm, iAttrs) { var DUMMY_SCOPE = { $destroy: angular.noop }, root = elm, childScope, destroyChildScope = function() { (childScope || DUMMY_SCOPE).$destroy(); }; iAttrs.$observe('html', function(html) { if (html) { destroyChildScope(); childScope = $scope.$new(false); var content = $compile(html)(childScope); root.replaceWith(content); root = content; } scope.$on('$destroy', destroyChildScope); }); } }; }]); angular.module('com.ngnice.app').controller("DemoController", function() { var vm = this; vm.html = '<h2>hello:<a ng-href="{{demo.link}}">Angular</a></h2>'; vm.link = 'https://angular.io/'; var i = 0 vm.change = function() { vm.html = '<h3>change after:<a ng-href="{{demo.link}}">'+(++i)+'</a></h3>' }; })
指令坚挺绑定属性HTML值的变化,当HTML内容存在的时候,它会尝试建立一个子scope,而后利用$compile服务来动态连接传入的HTML和这个子scope,在最后还会用它来替换掉当前DOM节点;建立独立子scope是为了方便每次销毁DOM的同时能很容易地把scope也销毁掉,销毁掉HTML compile带来的watchers函数。最后还须要在父scope被销毁的时候,也须要自动地销毁这个独立的子scope。