angularjs仿拉勾网webapp总结与记录
来源:互联网 发布:淘宝宝贝详情图模板 编辑:程序博客网 时间:2024/05/18 01:46
这是慕课网上的实战课程,使用的技术栈有bower+less+angular1.x+gulp。没有涉及到后端,数据是模拟的json数据。
gulp
其中gulp的配置在这里。
less
关于less部分,只使用了一些最基础的语法。如下:
- 文件引用
使用@import。
@import 'a.less';@import 'b.less';
- 定义变量
使用的了一个文件variabel.less
专门用来定义变量。在less中定义变量使用@。定义完成后以分号结束。
@defaultColor: #fff;@defaultWidth: 400px;
这样在其他文件里,这要引入了这个文件,就可以使用这些变量。
@import 'variable.less';body { color: @defaultColor;}.box { width: @defaultWidth;}
- 样式的嵌套
&表示引用自己。
body { color: @defaultColor; .box { background: red; &:hover { background: green; } }}
- unit函数
该函数用来删除或更换单位。
参数:
- dimension: 带单位或不带单位的数字。
- unit: (可选) 目标单位,如果省略此参数,则删除单位。
案例: unit(5, px)输出: 5px案例: unit(5em)输出: 5
- 函数
定义一个函数,如下:
.pt(@px) { padding-top: unit(@px / 37.5, rem);}
在使用的使用调用这个并传入参数即可。
.box { .pt(20);}
angular部分
angular使用的插件有:
- angular-ui-router
- angular-validation
- angular-cookie
- angular-animate
// app.jsangular.module('app', ['ui.router', 'ngCookies', 'validation', 'ngAnimate'])
在ui-router
中,首先是定义路由,如下:
angular.module('app').config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { $stateProvider .state('main', { // main是当前页面的id,以后要跳转到该页面使用ui-sref="main"或者$state.go('main'); url: '/main', templateUrl: 'view/mian.html', controller: 'mainCtrl' }) .state('login', { // 定义其他路由等 }) // 除了上述路由外,处理其他不匹配的路由 $urlRouterProvider.otherwise('main');}])
ui-sref
使用ui-router自带的ui-sref属性来定义将要跳转的页面的id。
<li ui-sref="main">跳转到main页面</li>
如果要传入参数,如下格式。()中的对象反映的是传入的参数键值对。
<li ui-sref="position({id: item.id})">跳转到position页面</li>
在position页面对应的控制器中,通过$state.params.id
取得查询键。
angular.module('app').controller('positionCtrl', ['$http', '$state', '$scope', function($http, $state, $scope) { $http.get('data/position.json', { params: { id: $state.params.id } }) .then(function() {}, function() {})}])
可以通过ui-sref-active
给选中的标签添加样式。比如菜单栏。
指令中的scope
关于指令中的scope请看这里,内容较多,我单独列了出来。
$index/$last
在使用ng-repeat
渲染元素时,可以使用两个内置的属性观察渲染情况。$scope.$index
来查看渲染的子元素的索引,$scope.$last(boolean)
来查看是否执行完成,如果是true,表示ng-repeat
执行完毕。
<button ng-click="showPositionList($index)" ng-repeat="cls in com.positionClass" ng-bind="cls.name"></button>
这个类似于导航栏的按钮,点击后控制器拿到这个$index
,根据不同的$index
传递给view层不同的数据。
$id/$parent$root
在任何一个控制器中,通过$scope.$id
,$scope.$parent
,$scope.$root
来表示当前作用域的id,父作用域,根作用域。
通常在angular应用的run方法中定义根作用域相关属性。
angular.module('app',[]) // 必须引入ng-route//config方法在整个页面中最先执行,先于run,.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { // 在这里配置路由}])// 通常将路由事件定义在根作用域下.run(function($rootScope) {//console.log($rootScope); $rootScope.$on('$routeChangeStart', function () { console.log(this) console.log(arguments); })})
value()和constant()
使用constant()来保存一个常量。
使用value()函数来缓存全局变量(需要的时候可以直接使用)。
constant()和value()方法之间一个最主要的区别是,常量可以注入到配置函数(.config())中,而值不行。
angular.module('app').constant('apikey', 'real')
angular.module('app').value('dict', {}) // 缓存全局变量.run(['dict', '$http', function(dict, $http) { $http.get('data/city.json').then(function(res) { dict.city = res.data; }) $http.get('data/salary.json').then(function(res) { dict.salary = res.data; }) $http.get('data/scale.json').then(function(res) { dict.scale = res.data; })}])
自定义过滤器
<!--过滤item--><li ng-repeat="item in data | filterByObj:filterObj">
filterByObj
是一个已经定义好的过滤器。它返回的函数中有两个参数,第一个list表示上述的data,第二个obj表示filterByObj:
后面的filterObj
。这个filterObj
对应父作用域的一个属性,根据情况而改变。从而达到筛选效果。
angular.module('app').filter('filterByObj', [function() { return function(list, obj) { var result = []; angular.forEach(list, function(item) { var isEqual = true; for(var e in obj) { if(item[e] !== obj[e]) { isEqual = false; } } if(isEqual) { result.push(item); } }) return result; }}])
$interval
var interval = $interval(fn, timedelay)$inteval.cancel(interval); // 使用cancel取消这个定时器// 在原生js中是interval = null;
阻止冒泡
ng-click
事件有一个事件对象$event
。stopPropagation
不需要加括号。
<li ng-click="$event.stopPropagation;select(item);"></li>
$watch
如果在指令中用到了某个属性,但是这个属性的值依赖于异步返回的结果,这时候就需要$watch这个值。否则报错。
// 1 父作用域<div app-company com="company"></div>// 这是副作用域控制器执行的$http.get('data/company.json?id='+id).then(function(res){ $scope.company = res.data;})// 2angular.module('app').directive('appPositionClass', [function() { return { restrict: 'A', replace: true, templateUrl: 'view/template/positionClass.html', scope: { com: '=' }, link: function($scope, element, attr) { $scope.$watch('com', function(newVal, oldVal, scope) { if(newVal){ $scope.showPositionList(0); } }) } }}])
可以看到指令要想获得com
属性,依赖于父作用域的$scope.company
。而通过一个异步操作才能返回。所以指令中就$watch
这个变量。
angular-validation
首先在index.html页面中引入angular-validation.js,然后再angular.module(‘app’, [‘validation’])加上依赖。
这个插件定义了一个$validationProvider
服务。用来设置表达式和验证消息。
// validation.jsangular.module('app').config(['$validationProvider', function($validationProvider) { var expression = { phone: /^1\d{10}$/, password: function(value) { return value.length > 5; }, required: function(value) { return !!value; } } var defaultMsg = { phone: { success: '', error: '11位手机号' }, password: { success: '', error: '长度至少6位' }, required: { success: '', error: '不能为空' } } $validationProvider.setExpression(expression).setDefaultMsg(defaultMsg);}])
在login页面中,做了简单的验证。
<div class="login"> <form class="d-b ta-c" name="form"> <div class="form-line ta-l p-r"> <span class="icon account va-t d-ib"></span> <input name="phone" validator="required,phone" ng-model="user.phone" class="d-ib" type="text" placeholder="输入手机号"> </div> <div class="form-line ta-l p-r"> <span class="icon lock va-t d-ib"></span> <input name="password" validator="required,password" ng-model="user.password" class="d-ib" type="password" placeholder="输入密码"> </div> <button class="login-btn" validation-submit="form" ng-click="submit();">登录</button> <button class="register-btn" ui-sref="register">注册</button> </form></div>
注意input
的validator
属性,这里是验证的表达式的内容,如果有多个,使用逗号隔开。这个内容对应validation.js
中的var expression
中的键。
注意<button validation-submit="form" ng-click="submit"></button>
这里,form是表单的name属性。
factory/service
我们使用factory或者service定义服务。service使用this来保存服务内容,类似构造函数。而factory使用返回值来保存服务内容。我们定义了一个cache服务。$cookies
是angular-cookies
插件提供的。两种写法如下:
// app.js中angular.module('app', ['ui.router', 'ngCookies', 'validation', 'ngAnimate']);
服务:
angular.module('app').service('cache', ['$cookies', function($cookies) { this.put = function(key, value) { $cookies.put(key, value); }; this.get = function(key) { return $cookies.get(key); }; this.remove = function(key) { return $cookies.remove(key); }}])
angular.module('app').factory('cache', ['$cookies', function($cookies) { return { put: function(key, value) { $cookies.put(key, value); }, get: function(key) { return $cookies.get(key); }, remove: function(key) { return $cookies.remove(key); } }}])
讲真,我觉得使用这个不如使用localStorage,简单快捷(涉及到sessionID用cookie?)。
装饰器
装饰器是非常强大的,它不仅可以应用在我们的我们自己的服务上,也可以对AngularJS的核心服务进行拦截、中断甚至替换功能的操作。事实上AngularJS中很多功能的测试就是借助$provide.decorator()
建立的。
由于这个项目没有后端,为了模拟post请求,我们需要修改$http内置的post请求。
angular.module('app').config(['$provide', function($provide) { $provide.decorator('$http', ['$delegate', '$q', function($delegate, $q) { $delegate.post = function(url, data, config) { var def = $q.defer(); $delegate.get(url).then(function(res) { def.resolve(res.data); }, function(err) { def.reject(err); }) return { success: function(cb) { def.promise.then(cb); }, error: function(cb) { def.promise.then(null, cb); } } } return $delegate; }])}])
decorator()函数可以接受两个参数。
- name (字符串)将要拦截的服务名称
- decoratorFn(函数)在服务实例化时调用该函数,这个函数由injector.invoke调用,可以将服务注入这个函数中。
$delegate
是可以进行装饰的最原始的服务,为了装饰其他服务,需要将其注入进装饰器。
$q
内置的$q服务用来在Angular中创建promise。如上所述,我们使用$q.deffer()
创建一个延迟对象def
。通常返回时通过return def.promise
得到一个promise对象。这里更进一步封装了。
上述的def
使用了两种方法,分别是:
- def.resolve(data)
- def.reject(err)
- def.notify(data) 上述未提到
如果返回值是def.promise
,它的then方法有三个参数。
var promise = $http.post(someurl);promise.then(function(data) { alert('success');}, funciton(err) { alert('failed');}, function(dataUpdate) { alert('update')})
更加详细的在:
浅谈Angular的 $q, defer, promise
总结
github地址
晚上花了几个小时写了总结,学完这个项目之后,确实学到了很多。在写博客的过程中,为了表述完全,又特定找了一些资料,看以前的代码。更加深了理解。
从今以后,每写一个项目都要做一次总结。
- angularjs仿拉勾网webapp总结与记录
- 走进大前端:AngularJS 仿拉勾网 WebApp 开发移动端单页应用
- WebApp实时开源框架Clouda入门使用与记录
- AngularJS开发WebApp的流程
- AngularJS开发WebApp的模块
- webapp开发要点记录
- webapp开发要点记录
- webapp开发问题记录
- 提交记录与总结
- WEBAPP开发技巧总结
- WEBAPP开发技巧总结
- WEBAPP开发技巧总结
- WEBAPP开发技巧总结
- WEBAPP开发技巧总结
- HTML5开发Webapp总结
- 滴滴:WebApp实践经验总结
- webApp项目开发总结
- phonegap------angularjs+ionic高大上的webApp
- Java环境变量配置
- CentOS6.5 yum升级gcc
- 谈嵌入式产品的敏捷开发
- Ext3.1.1(五)XTemplate使用案例
- python代码ssh自动连接ubuntu
- angularjs仿拉勾网webapp总结与记录
- Reverse Linked List II
- 长按手势
- Java代码块详解
- UML类图的几种关系的总结
- JAVA多用户商城系统源码
- Fastmodel在Ubuntu14.04下安装与错误处理
- Android创建原图的副本
- 获取autolayout约束后的控件