本小节,我们来完成搜索模块的开发,首先,配置搜索模块的路由,打开src/script/config/router.js文件:
.state('search',{ url:'/search/:id', templateUrl:'view/search.html', controller:'searchCtrl' });
然后,给搜索模块添加控制器,进入src/script/controller/文件夹,新建searchCtrl.js文件:
'use strict'; angular.module('app') .controller('searchCtrl',['$http', '$scope', function ($http, $scope) { }]);
现在来创建我们的搜索页面,在src/view/目录下,新建search.html文件:
<!-- 搜索条 --> <div class="search"> <button>取消</button> <input type="text"> <button>搜索</button> </div> <!-- tab切换 --> <div app-tab></div> <!-- 职位列表 --> <div app-position-list></div> <!-- 底部菜单 --> <div app-foot></div>
此时的页面效果如下图所示:
我们来给搜索页面添加样式,新建文件src/style/search.less文件,并引入index.less文件,样式代码我就省略了,添加完样式的页面搜索栏如下:
页面中间主体部分是一个tab切换的窗口,包含城市/薪资/公司规模,我们在src/view/template/目录下,新建tab.html组件模板,同时建立src/style/template/tab.less文件添加样式(样式代码省略),tab.html:
<ul class="tab"> <li class="d-ib ta-c active">城市</li> <li class="d-ib ta-c ">薪资</li> <li class="d-ib ta-c ">公司规模</li> </ul>
然后在src/script/directive/目录下创建tab自定义指令,新建文件tab.js:
'use strict'; angular.module('app').directive('appTab',[function(){ return { restrict:'A', replace:true, templateUrl:'view/template/tab.html' } }])
现在中间主体tab部分的组件已经嵌入进search模块中了,我们打开searchCtrl.js文件,给tab组件中的职位列表添加数据:
'use strict'; angular.module('app') .controller('searchCtrl', ['$http', '$scope', function($http, $scope) { $http.get('/data/positionList.json').success(function(resp) { $scope.positionList = resp; }) }]);
然后打开search.html文件,将获取的数据绑定到组件中:
<!-- 职位列表 --> <div app-position-list data="positionList"></div>
现在,我们的搜索模块已经可以看到职位列表了:
下面的工作,是给搜索模块添加一个弹出窗口,以显示筛选条件。进入search.html文件,在app-foot组件下方,添加组件app-sheet:
<!-- 底部菜单 --> <div app-foot></div> <!-- 筛选窗口 --> <div app-sheet></div>
然后新建app-sheet组件的模板文件,src/view/template/sheet.html
<div class="sheet" ng-show="visible"> <div class="wrap"> <ul> <li class="d-b ta-c">不限</li> <li class="d-b ta-c">少于50人</li> <li class="d-b ta-c">50~100</li> <li class="d-b ta-c">100~500</li> <li class="d-b ta-c">500人以上</li> </ul> <button>取消</button> </div> </div>
在sheet.html中,用ng-show来控制窗口显示与隐藏。
接着创建sheet组件的自定义指令文件src/script/directive/sheet.js
'use strict'; angular.module('app').directive('appSheet',[function(){ return { restrict:'A', replace:true, templateUrl:'view/template/sheet.html' } }])
同样我们需要在src/style/template/下创建sheet.less文件并引入到index.less文件中,样式代码省略。页面效果如下:
说明:在在sheet.html中,用 ng-show="visible"来隐藏窗口
现在,搜索模块的静态页面已经完成了,我们来实现它的业务逻辑代码,按照页面从上到下的顺序,首先实现搜索功能,打开search.html文件,给搜索栏添加数据模型、指令以及点击事件:
<!-- 搜索条 --> <div class="search-bar ta-c">
<!-- 添加点击事件,先清空name值,然后再调用search()函数 --> <button ng-click="name='';search();">取消</button>
<!-- 添加ng-model数据模型 --> <input ng-model="name" type="text" placeholder="搜索职位/公司/城市">
<!-- 给搜索添加点击事件search()函数 --> <button ng-click="search();">搜索</button> </div>
然后打开searchCtrl.js文件,添加search()函数执行数据查询:
'use strict'; angular.module('app') //注入服务$http $scope .controller('searchCtrl', ['$http', '$scope', function($http, $scope) { //先清空name值 $scope.name=""; //定义search()函数,执行数据查询 $scope.search = function() { $http.get('/data/positionList.json?name='+$scope.name).success(function(resp) { $scope.positionList = resp; }); }; //调用search()函数 $scope.search(); }]);
搜索栏部分的业务逻辑我们已经添加完成了,现在来处理中间tab切换窗口部分的逻辑,这部分我们要实现点击城市/薪资/公司规模的时候,弹出窗口显示筛选过滤条件的选择列表,我们将使用过滤器来实现这一功能。
首先打开src/view/template/tab.html文件,修改代码:
<ul class="tab"> <!-- 添加ng-repeat指令拿出可变的数据,然后使用ng-bind指令绑定到元素中,再添加一个ng-click指令绑定click()函数,实现tab切换的功能,在class类里,有一个三目运算,判断选中元素高亮的样式 --> <li ng-click="click(item)" ng-repeat="item in list" class="d-ib ta-c {{selectId===item.id?'active':''}}" ng-bind="item.name"></li> </ul>
然后,打开src/script/directive/tab.js文件,为tab切换添加点击事件:
'use strict'; angular.module('app').directive('appTab',[function(){ return { restrict:'A', replace:true, scope:{ list:'=', tabClick:'&' }, templateUrl:'view/template/tab.html', link:function($scope){ $scope.click = function(tab){ $scope.selectId = tab.id; $scope.tabClick(tab); } } } }]);
tab组件及其业务逻辑,我们已经完成了,下面进入src/script/config/目录下,创建dict.js来存放我们的全局变量:
'use strict'; //使用.value创建全局变量 angular.module('app').value('dict', {}).run(['dict', '$http', function(dict,$http){ $http.get('/data/city.json').success(function(resp){ dict.city = resp; }); $http.get('/data/salary.json').success(function(resp){ dict.salary = resp; }); $http.get('/data/scale.json').success(function(resp){ dict.scale = resp; }); }]);
打开src/view/search.html,修改app-tab部分的代码:
<!-- tab切换 --> <div app-tab list="tabList" tab-click="tClick(id,name)"></div>
定义好全局变量dict(我们采用依赖注入的方式使用这个全局变量),又给app-tab组件添加了数据接口和方法,打开searcjCtrl.js文件:
'use strict'; angular.module('app') //注入$http $scope dict .controller('searchCtrl', ['dict','$http', '$scope', function(dict, $http, $scope) { $scope.name=""; $scope.search = function() { $http.get('/data/positionList.json?name='+$scope.name).success(function(resp) { $scope.positionList = resp; }); }; $scope.search(); $scope.tabList = [{ id:'city', name:'城市' },{ id:'salary', name:'薪资' },{ id:'scale', name:'公司规模' }]; $scope.tClick = function(id,name){ console.log(id,name); }; }]);
此时,我们的tab组件已经可以显示分类标题了,下面要实现的是,点击分类标题的时候弹出筛选列表的功能,我们先来修改列表组件的模板和自定义指令,分别打开sheet.html和sheet.js:
sheet.html:
<div class="sheet" ng-show="visible" ng-click="visible=false;"> <div class="wrap"> <ul> <!-- 使用ng-repeat和ng-bind指令获取展示数据,并添加click事件 --> <li ng-click="select(item)" class="d-b ta-c" ng-repeat="item in list" ng-bind="item.name"></li> </ul> <!-- 给按钮添加click事件,使点击取消时列表消失 --> <button class="d-b" ng-click="visible=false;">取消</button> </div> </div>
sheet.js:
'use strict'; angular.module('app').directive('appSheet',[function(){ return { restrict:'A', replace:true, scope:{ list:'=', visible:'=', select:'&' }, templateUrl:'view/template/sheet.html' } }]);
sheet组件模板相关代码已经修改好了,现在打开search.html文件,修改一下app-sheet组件:
<div app-sheet select="sClick(id,name)" list="sheet.list" visible="sheet.visible"></div>
打开searchCtrl.js文件,我们来实现点击tab标题显示对应列表窗口的逻辑:
'use strict'; angular.module('app') //注入$http $scope dict .controller('searchCtrl', ['dict','$http', '$scope', function(dict, $http, $scope) { $scope.name=""; $scope.search = function() { $http.get('/data/positionList.json?name='+$scope.name).success(function(resp) { $scope.positionList = resp; }); }; $scope.search(); $scope.tabList = [{ id:'city', name:'城市' },{ id:'salary', name:'薪资' },{ id:'scale', name:'公司规模' }]; $scope.filterObj = {}; var tabId = ''; $scope.sheet = {}; $scope.tClick = function(id,name){ tabId = id; $scope.sheet.list = dict[id]; $scope.sheet.visible = true; }; $scope.sClick = function(id,name){ if(id){ angular.forEach($scope.tabList, function(item){ if(item.id===tabId){ item.name=name; } }); }else{ angular.forEach($scope.tabList, function(item){ if(item.id===tabId){ switch(item.id){ case 'city':item.name = '城市'; break; case 'salary':item.name = '薪资'; break; case 'scale':item.name = '公司规模'; break; } } }); }; }; }]);
现在,我们实现了点击列表项,实现tab标题替换的功能,但是,我们希望点击列表项,替换标题内容的同时,职位列表的内容也可以做出对应的筛选,这就要用到过滤器了,在src/script/目录下,新建filter文件夹并新建文件filterByObj.js:
'use strict'; 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; }; }]);
因为我们是要对职位列表进行过滤,所以要把过滤器放到职位列表组件内,打开src/view/template/positionlist.html文件:
<li ui-sref="position({id:item.id})" class="item" ng-repeat="item in data|filterByObj:filterObj">
然后,打开positionlist.js文件,添加过滤器暴露接口:
'use strict'; angular.module('app').directive('appPositionList',[function(){ return { restrict:'A', replace:true, templateUrl:'view/template/positionlist.html', scope:{ data:'=', filterObj:'=' } }; }]);
打开search.html文件,添加接口:
<!-- 职位列表 --> <div app-position-list data="positionList" class="search-list" filter-obj="filterObj"></div>
最后,打开searchCtrl.js文件,将我们的过滤器赋值:
'use strict'; angular.module('app') //注入$http $scope dict .controller('searchCtrl', ['dict','$http', '$scope', function(dict, $http, $scope) { $scope.name=""; $scope.search = function() { $http.get('/data/positionList.json?name='+$scope.name).success(function(resp) { $scope.positionList = resp; }); }; $scope.search(); $scope.tabList = [{ id:'city', name:'城市' },{ id:'salary', name:'薪资' },{ id:'scale', name:'公司规模' }]; $scope.filterObj = {}; var tabId = ''; $scope.sheet = {}; $scope.tClick = function(id,name){ tabId = id; $scope.sheet.list = dict[id]; $scope.sheet.visible = true; }; $scope.sClick = function(id,name){ if(id){ angular.forEach($scope.tabList, function(item){ if(item.id===tabId){ item.name=name; } }); $scope.filterObj[tabId + 'Id'] = id; }else{ delete $scope.filterObj[tabId + 'Id'] angular.forEach($scope.tabList, function(item){ if(item.id===tabId){ switch(item.id){ case 'city':item.name = '城市'; break; case 'salary':item.name = '薪资'; break; case 'scale':item.name = '公司规模'; break; } } }); }; }; }]);
现在就可以实现筛选功能了:
至此,搜索模块开发完成了。