javascript – 在AngularJS中使用带有自定义指令的不同控制器?

我创建了一个搜索框,用于两个不同的视图,一个用于搜索作业,另一个用于搜索公司.我为两者和单独的服务制作了两个独立的控制器.

这是搜索框的html –

<span class="searchButton"><i class="fa fa-search fa-2x"></i></span>
<input ng-change="companies.search()" 
       ng-model="companies.searchTerm" 
       ng-keydown="companies.deleteTerm($event)" 
       type="text" id="search-box" 
       style="width: 0px; visibility:hidden;"/>

这是我用来设置样式的脚本 –

<script type="text/javascript"> 
var toggleVar = true;
    $('.searchButton').on('click', function() {
        if(toggleVar) {
            $('.searchButton').animate({right: '210px'}, 400);
            $('#search-box').css("visibility", "visible");
            setTimeout(function() {
                $('.searchButton').css("color", "#444444");
            }, 200);
            $('#search-box').animate({ width: 185 }, 400).focus();
            toggleVar = false;
        }
        else {
            $('#search-box').animate({ width: 0 }, 400);
            $('.searchButton').animate({right: '25px'}, 400);
            setTimeout(function() {
                $('.searchButton').css("color", "#eeeeee");
            }, 300);
            toggleVar = true;
        }
    });

    $('#search-box').focusout(function() {
        if(!toggleVar) {
            $('#search-box').animate({ width: 0 }, 400);
            $('.searchButton').animate({right: '25px'}, 400);
            setTimeout(function() {
                $('.searchButton').css("color", "#eeeeee");
            }, 300);
            toggleVar = true;
        }
    });
</script>

控制器 –

angular.module('jobSeekerApp')
  .controller('CompaniesallCtrl', ['getAllCompanies', function (companiesService) {
    var ctrl = this;
    var count;
    ctrl.pageNumber = 1;
    ctrl.searchPageNumber = 1;
    ctrl.isSearching = false;
    ctrl.searchTerm = "";

    // Initial page load
    companiesService.getCompanies(ctrl.pageNumber)
      .then(function(response) {
        ctrl.companiesList = response.data.results;
        count = response.data.count;
        checkCount();
      }, function(error) {
        console.log(error);
      });

    // User clicks next button
    ctrl.getNext = function() {
      // If search is not being used
      if(ctrl.searchTerm === "" && ctrl.isSearching === false) {
        ctrl.pageNumber = ctrl.pageNumber + 1;
        companiesService.getCompanies(ctrl.pageNumber)
          .then(function(response) {
            ctrl.companiesList = ctrl.companiesList.concat(response.data.results);
            checkCount(); 
          }, function(error) {
            console.log(error);
          });
      }
      // If search is being used
      else {
        ctrl.searchPageNumber = ctrl.searchPageNumber + 1;
        companiesService.searchCompany(ctrl.searchPageNumber, ctrl.searchTerm)
          .then(function(response) {
            ctrl.companiesList = ctrl.companiesList.concat(response.data.results);
            checkCount();
          }, function(error) {
            console.log(error);
          });
      } 
    };

    // User backspaces to delete search term
    ctrl.deleteTerm = function (event) {
      if(event.keyCode === 8) {
        ctrl.searchTermLen = ctrl.searchTermLen - 1;
      }
      // If search box is empty
      ctrl.isSearching = ctrl.searchTermLen !== 0;
    };

    // User clicks search button
    ctrl.search = function() {
      ctrl.searchTermLen = ctrl.searchTerm.length;
      // If search box is empty, show normal results
      if(ctrl.searchTerm === "" && ctrl.isSearching === false) {
        ctrl.pageNumber = 1;
        companiesService.getCompanies(ctrl.pageNumber)
          .then(function(response) {
            ctrl.companiesList = response.data.results;
            count = response.data.count;
            checkCount();
          }, function(error) {
            console.log(error);
          });
      }
      // If search box is not empty, search the input
      else {
        ctrl.isSearching = true;
        ctrl.searchPageNumber = 1;
        companiesService.searchCompany(ctrl.searchPageNumber, ctrl.searchTerm)
          .then(function(response) {
            ctrl.companiesList = response.data.results;
            count = response.data.count;
            checkCount();
          }, function(error) {
            console.log(error);
          });
      }
    };

    // Function to hide and show next button
    function checkCount() {
      console.log(count);
      $(".nextButton").toggle(count > 10);
      count = count - 10;
    }
  }]);

我正在尝试为此制定一个指令,因为所有这些代码都是针对两个视图重复的.但是如何使指令与不同的控制器交互.我如何使这部分ng-change =“companies.search()”ng-model =“companies.searchTerm”ng-keydown =“companies.deleteTerm($event)”不依赖于控制器.
我是角色的新手,我不确定这是正确的方法还是我应该让代码分开?请帮忙.

最佳答案 服务器端搜索逻辑使其变得简单

如果您的搜索逻辑可能驻留在服务器上,并且只需在URL中设置查询变量就可以区分搜索作业或公司,那么就很容易了.您可以使用带有属性的1个搜索指令来说明要搜索的模块,并将其包含在您的HTTP请求中.

客户端搜索逻辑略微更具角度

如果您需要针对每种类型的搜索使用不同的客户端逻辑,请考虑这种方法,其中有1个常见搜索指令,以及每个自定义搜索的1个指令.

>公共搜索指令控制视图常见搜索功能
>一个限制的搜索公司指令:’A’和要求:’搜索’并执行特定于公司搜索的功能
>一个也限制的搜索作业指令:’A’和要求:’搜索’并执行特定于作业搜索的功能

概念是自定义搜索指令将其控制器/ api对象提供给公共搜索指令.公共搜索指令处理视图 – 控制器交互并调用提供的API函数以用于自定义搜索功能.

在Code中,这可能看起来像:

angular.module('SearchDemo', [])
.directive('search', function(){
    return {
        restrict: 'E',
        templateUrl: '/templates/search.tpl.html',
        controller: ['$scope', function($scope){
            $scope.results = [];

            this.setSearchAPI = function(searchAPI){
                this.api = searchAPI;
            };

            $scope.doSearch = function(query){
                $scope.results.length = 0;

                // here we call one of the custom controller functions
                if(this.api && angular.isFunction(this.api.getResults)){
                    var results = this.api.getResults(query);

                    // append the results onto $scope.results
                    // without creating a new array
                    $scope.results.push.apply($scope.results, results);
                }
            };
        }]
    };
})
.directive('searchCompanies', function(){
    return {
        restrict: 'A',
        require: ['search', 'searchCompanies'],
        link: function(scope, elem, attr, Ctrl){
            // here we pass the custom search-companies controller
            // to the common search controller
            Ctrl[0].setSearchAPI(Ctrl[1]);
        },
        controller: ['$scope', function($scope){
            // you need to design your common search API and 
            // implement the custom versions of those functions here

            // example:
            this.getResults = function(query){
                // TODO: load the results for company search
            };
        }]
    };
})
.directive('searchJobs', function(){
    return {
        restrict: 'A',
        require: ['search', 'searchJobs'],
        link: function(scope, elem, attr, Ctrl){
            // here we pass the custom search-jobs controller
            // to the common search controller
            Ctrl[0].setSearchAPI(Ctrl[1]);
        },
        controller: ['$scope', function($scope){
            // you need to design your common search API and 
            // implement the custom versions of those functions here

            // example:
            this.getResults = function(query){
                // TODO: load the results for job search
            };
        }]
    };
});

在模板中使用它看起来像:

< search search-companies>< / search>

< search search-jobs>< / search>

对一个指令进行多次搜索

如果您需要一个搜索指令来搜索公司和作业,则可以轻松扩展此概念.

改变是将搜索控制器的this.api变成一个数组.

angular.module('SearchDemo', [])
.directive('search', function(){
    return {
        restrict: 'E',
        templateUrl: '/templates/search.tpl.html',
        controller: ['$scope', function($scope){
            $scope.results = [];

            // this.api is now an array and can support 
            // multiple custom search controllers
            this.api = [];
            this.addSearchAPI = function(searchAPI){
                if(this.api.indexOf(searchAPI) == -1){
                    this.api.push(searchAPI);
                }
            };

            $scope.doSearch = function(query){
                $scope.results.length = 0;

                // here we call each of the custom controller functions
                for(var i=0; i < this.api.length; i++){
                    var api = this.api[i];
                    if(angular.isFunction(api.getResults)){
                        var results = api.getResults(query);

                        $scope.results.push.apply($scope.results, results);
                    }
                }
            };
        }]
    };
})
.directive('searchCompanies', function(){
    return {
        restrict: 'A',
        require: ['search', 'searchCompanies'],
        link: function(scope, elem, attr, Ctrl){
            // here we pass the custom search-companies controller
            // to the common search controller
            Ctrl[0].addSearchAPI(Ctrl[1]);
        },
        controller: ['$scope', function($scope){
            // you need to design your common search API and 
            // implement the custom versions of those functions here

            // example:
            this.getResults = function(query){
                // TODO: load the results for company search
            };
        }]
    };
})
.directive('searchJobs', function(){
    return {
        restrict: 'A',
        require: ['search', 'searchJobs'],
        link: function(scope, elem, attr, Ctrl){
            // here we pass the custom search-jobs controller
            // to the common search controller
            Ctrl[0].addSearchAPI(Ctrl[1]);
        },
        controller: ['$scope', function($scope){
            // you need to design your common search API and 
            // implement the custom versions of those functions here

            // example:
            this.getResults = function(query){
                // TODO: load the results for job search
            };
        }]
    };
});

在模板中使用它看起来像:

< search search-companies search-jobs>< / search>

点赞