Live2D 看板娘

本小节,我们来完成搜索模块的开发,首先,配置搜索模块的路由,打开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;
                        }
                    }
                });
            };
        };
    }]);

现在就可以实现筛选功能了:

至此,搜索模块开发完成了。

原文地址:https://www.cnblogs.com/jiangtengteng/p/6843537.html