我创建了一个搜索框,用于两个不同的视图,一个用于搜索作业,另一个用于搜索公司。我为两者和单独的服务制作了两个独立的控制器。
这是搜索框的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)"
不依赖于控制器。
我是角色的新手,我不确定这是正确的方法还是我应该让代码分开?请帮忙。
答案 0 :(得分:1)
服务器端搜索逻辑使其变得简单
如果您的搜索逻辑可能驻留在服务器上,并且只需在URL中设置查询变量就可以区分搜索作业或公司,那么就很容易了。您可以使用带有属性的1个搜索指令来说明要搜索的模块,并将其包含在您的HTTP请求中。
客户端搜索逻辑略微更具角度
如果您需要针对每种类型的搜索使用不同的客户端逻辑,请考虑这种方法,其中有1个常用search
指令,以及每个自定义搜索的1个指令。
通用搜索指令控制视图+常用搜索功能
搜索公司指令restrict: 'A'
和require: 'search'
并执行特定于公司搜索的功能
一个也是restrict: 'A'
和require: 'search'
的搜索作业指令,并执行特定于求职的功能
概念是自定义搜索指令将其控制器/ api对象提供给公共搜索指令。公共搜索指令处理视图 - 控制器交互并调用提供的API函数以实现自定义搜索功能。
在代码中,这可能类似于:
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>
答案 1 :(得分:0)
您必须将数据源或服务传递给指令并从那里绑定事件。
<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>
在此示例中,我使用data-source
传递数组,但您当然可以使用服务。
然后你的指令应该使用scope
属性将你在source
中作为参数传递的内容分配给指令的范围。
您将使用elem
参数中的指令输入绑定所需的所有参数。
(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);
使用scope.$parent
我觉得有点hacky并限制使用此指令成为控制器的直接子项,但我认为这是让你入门的好方法。
您可以尝试一下:https://plnkr.co/edit/A3jzjek6hyjK4Btk34Vc?p=preview
这个例子中只有几个注释。
希望它有所帮助。