背景 我正在开发一个显示文章列表的角度应用程序。可以通过各种设置修改列表。一个这样的设置是这些文章的来源。将来源视为新闻机构:文章来自特定来源:
因此,当用户点击“来源”链接时,会出现一个下拉菜单,其中包含来源列表。用户可以选择这些来源的任何组合。还有一个“全选”和“全部清除”按钮可以选择所有来源或取消全部:
问题: 因此,每次用户选择或取消选择源时,都应该将http请求发送到服务器,并且应该更新文章列表。
我的问题是,我不知道如何调用将发送http请求的函数(在其下面的代码片段中称为updateArticleList()
)。
1)如果我将函数绑定到ng-click
并将其设置在label
标记上:
<ul>
<li ng-repeat="source in sources">
<label ng-click="updateArticleList()">
<input type="checkbox" ng-model="source.selected">
{{source.title}}
</label>
</li>
</ul>
然后点击标签会触发该功能两次(一次用于label
,显然,一次用于input
)。不好。
2)如果我将函数绑定到ng-change
标记上的input
:
<ul>
<li ng-repeat="source in sources">
<label>
<input type="checkbox" ng-model="source.selected"
ng-change="updateArticleList()">
{{source.title}}
</label>
</li>
</ul>
然后,一旦我点击“全选”或“清除”按钮,这将改变所有复选框的状态并发送大量的http请求。也不好。
现在,我正在尝试使用setTimeout
来解决这个问题,以便过滤掉对函数的一连串调用,就像这样(通过ng-click调用函数的示例):
var requestAllowed = true;
var debounceRequests = function(){
requestAllowed = false;
setTimeout(function(){
requestAllowed = true;
}, 5);
};
scope.updateArticleList = function(){
if (requestAllowed === true){
// prevent the second call to the function from ng-click
debounceRequests();
// also, give time for the input to register ng-click on the label
setTimeout(function(){
// finally, send an http request
getArticles();
}, 5);
}
};
但这看起来很脏。
所以,我的问题是,在这种情况下发出http请求的好方法是什么?
最好不要使用额外的js库。
==================
更新:
这是由“全选”触发的功能:
scope.selectAllSources = function(){
scope.sources.forEach(function(source){
source.selected = true;
});
scope.updateArticleList();
};
答案 0 :(得分:2)
您应该使用ng-change
。
ng-change
仅在输入更改模型时触发 - 而不是相反。您的selectAll
应该更改模型。我猜你正在做&#34;选择全部&#34;不同。
$scope.selectAll = function(){
for (var i = 0; i < $scope.sources.length; i++) {
$scope.sources[i].selected = true; // this does not fire `ng-change`
}
$scope.updateArticleList();
}
编辑:根据OP关于每次更改提交所有来源的评论,以下是如何实现这一目标的更完整的概念示例:
<li ng-repeat="source in sources">
<label>
<input type="checkbox" ng-model="source.selected" ng-change="updateArticleList()">
{{source.title}}
</label>
</li>
<button ng-click="selectAll()">select all</button>
答案 1 :(得分:1)
我更喜欢你的第一个解决方案,在探索后我记得一个类似的问题:Angular.js ng-click events on labels are firing twice
因此,您可以做的解决方法是检查事件元素并确保标记正确。
$scope.updateArticleList = function(event){
if(event.toElement.tagName == 'LABEL'){
//run code
}
};
HTML
<label ng-click="updateArticleList($event)">
JSFiddle:http://jsfiddle.net/4p48q63j/
答案 2 :(得分:0)
<ul>
<li ng-repeat="source in sources">
<label>
<input type="checkbox" ng-model="source.selected"
ng-change="updateArticleList(source.selected)">
{{source.title}}
</label>
</li>
</ul>
控制器; 个人选择......
$scope.updateArticleList=function(checked)
{
if(checked==true)
{
//Call to service
}
}
对于selecteAll(按钮/链接),有多种方式可以使用....
$scope.selectAll = function(){
angular.forEach($scope.sources,function(source,$index){
// model value will be true for all sources....
//Call to service
});
};