关于页面样式说明:博客里写的只有html和js,没有写样式,我就不一一把样式代码贴出来了,就简单说一下我们写样式的主体思路,样式添加在src/style/目录下,这个项目我们用less来添加样式。在style目录下,有index.less和variable.less文件,还有一个template的文件夹(用于存放各个视图的样式表文件以及property.less),index.less文件是总输出文件,template目录下的样式表会通过@import的方式引入到index.less文件中,再通过gulp解析合并到输出文件index.css文件,variable.less文件用于存放变量,property.less用于存放添加类,如浮动类。
4.1 head部分
进入main.html文件,写入代码:
<!-- app头部 -->
<div app-head></div>
<!-- app主体 -->
<div app-position></div>
<!-- app底部 -->
<div app-foot></div>
然后我们在src/view/template/目录下,创建head.html,作为app-head部分的引入模板:
<div class="head">
<span>10秒定制职位</span>
<button>去定制</button>
</div>
现在,我们在src/script/目录下新建directive文件夹(用于存放指令文件),在directive文件夹下新建head.js文件,写入代码:
'use strict';
angular.module('app').directive('appHead',[function(){
return{
restrict:'A',
replace:true,
templateUrl:'view/template/head.html'
}
}]);
在src/style/template/head.less里添加样式后预览我们的应用,可以看到头部如下:
4.2 foot部分
foot部分的开发过程和头部基本相同,先在src/view/template/目录下建立foot.html文件作为foot部分视图引入模板:
<ul class="foot">
<li class="d-ib ta-c" ui-sref="main" ui-sref-active="select"><i></i><span></span>职位</li>
<li class="d-ib ta-c" ui-sref="search" ui-sref-active="select"><i></i><span></span>搜索</li>
<li class="d-ib ta-c" ui-sref="my" ui-sref-active="select"><i></i><span></span>我</li>
</ul>
代码说明,class为样式,ui-sref指向的是跳转切换的页面(里面的值现在只有main页面存在,search和my是空的,因为不填内容会报错),ui-sref-active是li被选中时的状态,指定被选中时的类名为select,默认选中项为"职位"。
建立完底部视图模板后,新建foot.js文件在src/script/directive/目录下,添加指令代码:
'use strict';
angular.module('app').directive('appFoot',[function(){
return {
restrict:'A',
replace:true,
templateUrl:'view/template/foot.html'
}
}]);
然后在src/style/template/目录下创建foot.less文件,添加foot部分的样式,预览效果如下:
4.3 职位列表部分
4.3.1 开发顶层职位列表
在src/view/template/目录下建立positionlist.html文件,在src/script/directive/目录下建立positionlist.js文件,分别写入视图代码及指令代码:
positionlist.html:
<ul class="position-list">
<li class="item">
<img class="logo" src="" alt="">
<h3 class="title">销售</h3>
<p class="text">千度(上海)互联网<br/>2017-05-04</p>
</li>
</ul>
positionlist.js:
'use strict';
angular.module('app').directive('appPosition',[function(){
return {
restrict:'A',
replace:true,
templateUrl:'view/template/positionlist.html'
}
}]);
此时,职位列表模板的内容就被显示在了页面中,然后在src/style/template/目录下创建positionlist.less文件,添加职位列表部分的样式即可,加好样式的页面如下:
现在,应用职位列表页面的信息,还是我们自己写进去的死信息,怎么用angular变成活的信息呢,这就需要用到$scope服务来完成数据双向绑定的功能了,打开mainCtrl.js文件,我们先在里面添加两条数据:
'use strict';
angular.module('app')
.controller('mainCtrl',['$scope',function ($scope) {
$scope.list=[{
id:'1',
jobname:'销售',
imgsrc:'image/qd.jpg',
companyname:'千度',
city:'上海',
industry:'互联网',
time:'2017-05-04'
},
{
id:'2',
jobname:'文员',
imgsrc:'image/qd.jpg',
companyname:'千度',
city:'上海',
industry:'互联网',
time:'2017-05-04'
}];
}]);
然后,打开positionlist.js文件,添加一个数据接口:
'use strict';
angular.module('app').directive('appPosition',[function(){
return {
restrict:'A',
replace:true,
templateUrl:'view/template/positionlist.html',
scope:{
data:'='
}
};
}]);
上面代码中的scope:{data:'='},就可以把我们作用域中的数据暴露给外部,这样在引用的时候,就可以尽量降低耦合度,而这个暴露出来的接口,使用方法是,在我们需要绑定数据的地方,data指向作用域中的数据,这里指向的就是list数组,具体操作方法是,打开main.html文件:
<div app-position data="list"></div>
然后,进入positionlist.html文件,进行数据绑定:
<ul class="position-list bg-w">
<li class="item" ng-repeat="item in data">
<img class="f-l logo" ng-src="{{item.imgsrc}}" alt="">
<h3 class="title" ng-bind="item.jobname"></h3>
<p class="text" ng-bind="item.companyname+'('+item.city+')'+item.industry"></p>
<p class="text" ng-bind="item.time"></p>
</li>
</ul>
这样,我们就可以在预览页面看到作用域中的数据了:
4.3.2 职位模块二级页面--职位详情页开发
在src/view/目录下创建position.html文件,写入内容:
<div app-head-bar></div>
然后在src/script/controller/下创建控制器文件positionCtrl.js:
'use strict';
angular.module('app')
.controller('positionCtrl',['$scope',function ($scope) {
}]);
之后,打开路由设置文件router.js,添加职位详情页路由信息:
.state('position',{
url:'/position/:id',
templateUrl:'view/position.html',
controller:'positionCtrl'
});
设置好路由后,就可以设置页面跳转了,这里我们还是用ui-sref来实现页面跳转,打开文件positionlist.html:
<ul class="position-list bg-w">
<li ui-sref="position({id:item.id})" class="item" ng-repeat="item in data">
现在的position页面还没有内容,我们先给他添加个头部,在src/view/template/下新建headbar.html:
<div class="head ta-c p-r">
<span class="p-a c-w back-btn"><</span>
<span class="c-w">职位详情</span>
</div>
然后在src/script/directive/目录下,建立headbar.js,将头部模板引入position页面:
'use strict';
angular.module('app').directive('appHeadBar',[function(){
return{
restrict:'A',
replace:true,
templateUrl:'view/template/headbar.html'
}
}]);
而在headbar.html文件中,我们不能将职位详情写成死的,而且,返回箭头也要给他添加功能,所以将headbar.html做如下修改:
<div class="head ta-c p-r"> <span class="p-a c-w back-btn" ng-click="back()"><</span> <span class="c-w" ng-bind="text"></span> </div>
上面代码中,text是scope暴露出来的接口,而back()是一个事件方法,打开headbar.js文件,对代码做如下修改:
'use strict';
angular.module('app').directive('appHeadBar',[function(){
return{
restrict:'A',
replace:true,
templateUrl:'view/template/headbar.html',
scope:{
text:'@'
},
link:function(scope){
scope.back = function(){
window.history.back();
};
}
};
}]);
然后,打开position.html文件,给其添加text接口属性并传入值,再把页面的其他代码构建出来:
<div app-head-bar text="职位详情"></div>
<div app-position-info></div>
<div app-company></div>
<div class="bg-w position-desc">
<h5>职位描述</h5>
<pre class="ta-l">
岗位职责:
1.销售产品
</pre>
</div>
<button>投个简历</button>
新建position.less文件到src/style/目录下,为position页面添加样式后,页面效果如下:
现在职位详情页的头部和底部的内容以及中间不需要模板组件的部分,我们已经完成了,下面对中间主体模板部分内容进行填充,过程与之前的相同,我写的简略一点。
在src/view/template/目录下,建立positioninfo.html模板,同时在src/script/directive/目录下建立positioninfo.js指令文件,分别写入如下内容:
positioninfo.html模板:
<div class="bg-w position-info">
<p>
<span>销售</span>
<span>3K-5K</span>
</p>
<p>
<span>上海</span>
<span>1-3年</span>
<span>专科</span>
</p>
<p>成长空间大</p>
<img ng-src="{{imagePath}}" class="p-a">
</div>
positioninfo.js指令文件:
'use stict';
angular.module('app').directive('appPositionInfo',[function(){
return {
restrict:'A',
replace:true,
templateUrl:'view/template/positioninfo.html',
scope:{
isActive:'='
},
link:function($scope){
$scope.imagePath = $scope.isActive?'image/star-active.png':'image/star.png';
}
};
}]);
然后在src/style/template/目录下,建立positioninfo的样式文件positioninfo.less,写入样式后,页面效果如下:
接着添加公司组件,我下面用『路径 --> 文件』的形式,来表面文件创建目录啦。
src/view/template/ --> company.html
<div class="bg-w company-info p-r">
<img src="image/qd.jpg" class="p-a">
<p>千度</p>
<p>互联网/A轮/50-150人</p>
</div>
src/script/directive/ --> company.js
'use strict';
angular.module('app').directive('appCompany',[function(){
return {
restrict:'A',
replace:true,
templateUrl:'view/template/company.html'
}
}]);
src/style/template/ --> company.less less代码省略,页面效果如下:
4.3.3 职位模块三级页面--公司详情页开发
添加公司详情页模板 src/view/ --> company.html
<div app-head-bar text="公司职位"></div> <div app-company></div> <div app-position-class></div>
src/script/config/ --> router.js 添加公司详情页路由
.state('company',{ url:'/company/:id', templateUrl:'view/company.html', controller:'companyCtrl' });
src/script/controller/ --> companyCtrl.js 添加公司详情页控制器
'use strict'; angular.module('app') .controller('companyCtrl',['$scope',function ($scope) { }]);
打开src/view/template/ --> company.html 添加公司详情页跳转页面 ui-sref="company({id:1})"
<div class="bg-w company-info p-r" ui-sref="company({id:1})"> <img src="image/qd.jpg" class="p-a"> <p>千度</p> <p>互联网/A轮/50-150人</p> </div>
创建文件 src/view/template/ --> positionClass.html,添加公司详情页app-position-class组件模板
<div class="position-class"> <h5>职位分类</h5> <button class="active">技术</button> <button>运营</button> <ul> <li class="p-r"> <p>IOS前端工程师</p> <p>2017-4-5 09:30</p> <span class="p-a">15K-20K</span> </li> </ul> </div>
创建src/script/directive/ --> positionClass.js,给公司详情页app-position-class组件模板添加自定义指令:
'use stict'; angular.module('app').directive('appPositionClass',[function(){ return { restrict:'A', replace:true, templateUrl:'view/template/positionClass.html' }; }]);
创建src/style/template/ --> positionClass.less文件给公司详情页添加样式,并引入index.less。
现在,公司详情页的预览如下:
现在,职位模块的静态页面都已经开发完了,现在可以开始开发我们的业务逻辑了。
大家还记得吗,之前我们在mainCtrl.js文件中,写的是假数据,用数组对象存起来的,但是这样我们没有办法跟后端交互,如果我们要实现与后端的交互,需要使用$http服务来发送请求(这里我们没有连接数据库,获取的数据是json文件中的数据,相关的json文件,我都准备好了,放在src/data/目录下),打开mainCtrl.js:
'use strict'; angular.module('app') .controller('mainCtrl',['$http', '$scope', function ($http, $scope) { $http.get('/data/positionList.json').success(function(resp){ $scope.list=resp; }); }]);
我们可以根据返回的数据,对positionlist.html里的输出内容进行调整:
<ul class="position-list bg-w"> <li ui-sref="position({id:item.id})" class="item" ng-repeat="item in data"> <img class="f-l logo" ng-src="{{item.imageUrl}}" alt=""> <h3 class="title" ng-bind="item.job"></h3> <p class="text" ng-bind="item.companyName+'('+item.cityName+')'+item.industryName"></p> <p class="text" ng-bind="item.date"></p> <div class="clear"></div> </li> </ul>
现在,我们来预览一下主页(图片我没有添加,所以会显示破碎...):
下面我们来添加职位详情页的业务逻辑,职位详情页包含三个模块,分别是职位信息,公司信息以及职位描述,打开src/view//position.html文件:
<div app-head-bar text="职位详情"></div> <div app-position-info pos="position" is-login="isLogin"></div> <div app-company com="company"></div> <div class="bg-w position-desc"> <h5>职位描述</h5> <pre class="ta-l" ng-bind="position.description"></pre> </div> <button class="bottom-btn c-w" ng-bind="isLogin?'投个简历':'去登录'"></button>
这部分代码,在职位信息部分添加了 pos="position" is-login="isLogin"来连接接口和判断是否登录,接口我们稍候添加,在公司信息部分连接的是 com="company"接口,而职位描述部分绑定的是职位信息接口的数据,在最下面的按钮,添加了一个三目运算,来判断,登录状态和未登录状态,按钮展示的文字。
然后我们打开src/view/template/positioninfo.html以及src/script/directive/positioninfo.js,绑定职位信息组件及修改其自定义:
src/view/template/positioninfo.html:
<div class="bg-w position-info"> <p> <span ng-bind="pos.name"></span> <span ng-bind="pos.salaryName" class="ml c-r"></span> </p> <p> <span ng-bind="pos.cityName"></span> <span ng-bind="pos.experience" class="ml"></span> <span ng-bind="pos.education" class="ml"></span> </p> <p ng-bind="pos.benefit"></p> <img ng-show="isLogin" ng-src="{{imagePath}}" class="p-a"> </div>
src/script/directive/positioninfo.js:
'use stict'; angular.module('app').directive('appPositionInfo',[function(){ return { restrict:'A', replace:true, templateUrl:'view/template/positioninfo.html', scope:{ isActive:'=', isLogin:'=', pos:'=' }, link:function($scope){ $scope.imagePath = $scope.isActive?'image/star-active.png':'image/star.png'; } } }]);
然后是公司信息组件及指令:
src/view/template/company.html:
<div class="bg-w company-info p-r" ui-sref="company({id:com.id})"> <img ng-src="{{com.imageUrl}}" class="p-a"> <p ng-bind="com.name"></p> <p ng-bind="com.industry+'/'+com.state+'/'+com.people"></p> </div>
src/script/directive/company.js:
'use strict'; angular.module('app').directive('appCompany',[function(){ return { restrict:'A', replace:true, scope:{ com:'=' }, templateUrl:'view/template/company.html' } }]);
现在,我们打开src/script/controller/positionCtrl.js文件,来给职位模块添加业务逻辑:
'use strict'; angular.module('app') .controller('positionCtrl', ['$q', '$http', '$state', '$scope', function($q, $http, $state, $scope) { $scope.isLogin = false; function getPosition() { var def = $q.defer(); $http.get('/data/position.json?id=' + $state.params.id).success(function(resp) { $scope.position = resp; def.resolve(resp); }).error(function(err){ def.reject(err); }); return def.promise; }; function getCompany(id){ $http.get('/data/company.json?id='+id).success(function(resp){ $scope.company = resp; }) } getPosition().then(function(obj){ getCompany(obj.companyId); }); }]);
最后是公司职位页的业务逻辑,打开文件src/view/company.html,引入数据接口:
<div app-head-bar text="公司职位"></div> <div app-company com="company"></div> <div app-position-class com="company"></div>
打开src/script/controller/companyCtrl.js文件,获取公司信息数据:
'use strict'; angular.module('app') .controller('companyCtrl',['$http','$state', '$scope',function ($http, $state, $scope) { $http.get('/data/company.json?'+$state.params.id).success(function(resp){ $scope.company = resp; }) }]);
然后打开src/view/template/positionClass.html文件,给职位分类组件绑定数据以及点击事件:
<div class="position-class"> <h5>职位分类</h5> <button ng-click="showPositionList($index)" class="{{$index===isActive?'active':''}}" ng-repeat="cls in com.positionClass" ng-bind="cls.name"></button> <ul> <li class="p-r" ng-repeat="pos in positionList"> <p ng-bind="pos.name"></p> <p ng-bind="pos.createdDate"></p> <span ng-bind="pos.salary" class="p-a"></span> </li> </ul> </div>
现在,打开src/script/directive/positionClass.js文件,给职位分类组件添加数据接口以及点击事件函数:
'use stict'; angular.module('app').directive('appPositionClass', [function() { return { restrict: 'A', replace: true, scope: { com: '=' }, templateUrl: 'view/template/positionClass.html', link: function($scope) { $scope.showPositionList = function(idx) { $scope.positionList = $scope.com.positionClass[idx].positionList; $scope.isActive = idx; } $scope.$watch('com', function(newValue) { if (newValue) { $scope.showPositionList(0); }; }); } }; }]);
至此,职位模块开发完毕了,我们来预览一下效果: