Helpex - Trao đổi & giúp đỡ Đăng nhập
4

Tôi đã tạo một hộp tìm kiếm đang được sử dụng trên hai chế độ xem khác nhau, một là để tìm kiếm việc làm và một là để tìm kiếm các công ty. Tôi đã tạo hai bộ điều khiển riêng biệt cho cả hai và các dịch vụ riêng biệt.

Đây là html cho hộp tìm kiếm -

<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;"/>

Đây là một tập lệnh tôi đang sử dụng để tạo kiểu cho nó -

<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>

Bộ điều khiển -

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;
    }
  }]);

Tôi đang cố gắng thực hiện một chỉ thị cho điều này, vì tất cả mã này đang được lặp lại cho cả hai chế độ xem. Nhưng làm cách nào để làm cho chỉ thị tương tác với các bộ điều khiển khác nhau. Và làm cách nào để phần này ng-change="companies.search()" ng-model="companies.searchTerm" ng-keydown="companies.deleteTerm($event)"không bị phụ thuộc vào các bộ điều khiển. Tôi mới làm quen với góc cạnh và không chắc liệu đây có phải là cách tiếp cận phù hợp hay tôi nên để mã giữ nguyên riêng biệt? Xin vui lòng giúp đỡ.

4 hữu ích 2 bình luận 2.9k xem chia sẻ
1

Logic tìm kiếm phía máy chủ làm cho nó trở nên đơn giản

Nếu có thể logic tìm kiếm của bạn nằm trên máy chủ và việc tìm kiếm công việc hoặc công ty có thể được phân biệt bằng cách chỉ cần đặt một biến truy vấn trong URL, thì thật dễ dàng. Bạn có thể sử dụng 1 chỉ thị tìm kiếm với một thuộc tính để cho biết mô-đun nào cần tìm kiếm và đưa mô-đun này vào yêu cầu HTTP của bạn.

Logic tìm kiếm phía máy khách góc cạnh hơn một chút

Nếu bạn cần lôgic phía máy khách khác nhau cho từng loại tìm kiếm, hãy xem xét cách tiếp cận này khi có 1 searchchỉ thị chung , cộng với 1 chỉ thị cho mỗi tìm kiếm tùy chỉnh.

  1. chế độ xem điều khiển chỉ thị tìm kiếm chung + chức năng tìm kiếm chung

  2. một tìm kiếm các công ty chỉ có nghĩa là restrict: 'A'require: 'search'và thực hiện các chức năng cụ thể để việc tìm kiếm công ty

  3. một chỉ thị tìm kiếm công việc mà còn là restrict: 'A'require: 'search'và thực hiện các chức năng cụ thể để việc tìm kiếm công việc

Khái niệm là các chỉ thị tìm kiếm tùy chỉnh sẽ cung cấp đối tượng controller / api của chúng cho chỉ thị tìm kiếm chung. Chỉ thị tìm kiếm chung xử lý tương tác giữa chế độ xem và bộ điều khiển và gọi các hàm API được cung cấp cho chức năng tìm kiếm tùy chỉnh.

Trong Code , điều này có thể trông giống như:

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
            };
        }]
    };
});

Và sử dụng nó trong mẫu sẽ giống như sau:

<search search-companies></search>

<search search-jobs></search>

Nhiều tìm kiếm trên một chỉ thị

Khái niệm này có thể dễ dàng mở rộng nếu bạn cần có một chỉ thị tìm kiếm để tìm kiếm cả công ty và việc làm.

Thay đổi sẽ là biến bộ điều khiển tìm kiếm this.apithành một mảng.

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
            };
        }]
    };
});

Và sử dụng nó trong mẫu sẽ giống như sau:

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

1 hữu ích 0 bình luận chia sẻ
0

Bạn sẽ phải chuyển nguồn dữ liệu hoặc dịch vụ của mình tới chỉ thị và ràng buộc các sự kiện từ đó.

<body ng-app="customSearchDirective">
  <div ng-controller="Controller">

  <input type="text" placeholder="Search a Company" data-custom-search data-source="companies" />
  <input type="text" placeholder="Search for People" data-custom-search data-source="people" />

  <hr>
  Searching In: {{ searchSource }}
  <br/>
  Search Result is At: {{ results }}
</div>
</body>

Trong mẫu này, tôi đang sử dụng data-sourceđể truyền một mảng nhưng tất nhiên bạn có thể sử dụng một dịch vụ.

Sau đó, chỉ thị của bạn nên sử dụng scopethuộc tính để gán những gì bạn đã truyền dưới dạng tham số vào sourcephạm vi của chỉ thị.

Bạn sẽ có đầu vào đang sử dụng chỉ thị trong elemtham số để ràng buộc tất cả các tham số mà bạn mong muốn.

(function(angular) {
  'use strict';

  angular.module('customSearchDirective', [])


  .controller('Controller', ['$scope', function($scope) {
    $scope.companies = ['Microsoft', 'ID Software', 'Tesla'];
    $scope.people = ['Gill Bates', 'Cohn Jarmack', 'Melon Musk'];
    $scope.results = [];
    $scope.searchSource = [];
  }])


  .directive('customSearch', [function() {
    function link(scope, element, attrs) {
      element.on("change", function(e) {
        var searchTerm = e.target.value;
        scope.$parent.$apply(function() {
          scope.$parent.searchSource = scope.source;
          scope.$parent.results = scope.source.indexOf(searchTerm);
        });
      });
    }

    return {
      scope: {
        source: '='
      },
      link: link
    };
  }]);
})(window.angular);

Sử dụng scope.$parentcảm thấy một chút hacky Tôi biết và hạn chế việc sử dụng các chỉ thị này là một đứa trẻ trực tiếp của bộ điều khiển nhưng tôi nghĩ rằng đó là một cách tốt để giúp bạn bắt đầu.

Bạn có thể dùng thử: https://plnkr.co/edit/A3jzjek6hyjK4Btk34Vc?p=preview

Chỉ cần một vài lưu ý từ ví dụ.

  • Sự kiện thay đổi hoạt động sau khi bạn xóa tiêu điểm khỏi hộp văn bản (không phải khi bạn đang nhập
  • Bạn sẽ phải tìm kiếm chuỗi chính xác để có được một kết quả phù hợp

Hy vọng nó giúp.

0 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ javascript angularjs angularjs-directive , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading