AngularJS承诺并使用自定义过滤器计时
关于定制过滤器的计时,我现在非常头疼。 我有一个演示(学习角度)画廊应用程序,其中我使用带有复选框的自定义过滤器来选择不同类别的照片 Simptoms:当在ng repeat指令上使用自定义过滤器时,我注意到。。。经过几个小时的调试,我得出结论,问题是当过滤器运行时,JSON中的数据不在那里,尽管没有过滤器,一切似乎都正常加载 这里有一个用于此的plnkr(我复制粘贴了代码,对其进行了一点修改,尚未工作,将在早上修复它,但这是代码) 我开始在我的服务中使用延迟和承诺来获取JSON数据,这样控制器和其他所有人都会等待数据加载,就像这样[services]AngularJS承诺并使用自定义过滤器计时,angularjs,filter,timing,promise,Angularjs,Filter,Timing,Promise,关于定制过滤器的计时,我现在非常头疼。 我有一个演示(学习角度)画廊应用程序,其中我使用带有复选框的自定义过滤器来选择不同类别的照片 Simptoms:当在ng repeat指令上使用自定义过滤器时,我注意到。。。经过几个小时的调试,我得出结论,问题是当过滤器运行时,JSON中的数据不在那里,尽管没有过滤器,一切似乎都正常加载 这里有一个用于此的plnkr(我复制粘贴了代码,对其进行了一点修改,尚未工作,将在早上修复它,但这是代码) 我开始在我的服务中使用延迟和承诺来获取JSON数据,这样控制器
angular.module('services', []).factory('getAllPosts', ['$http', '$q', '$timeout',
function($http, $q, $timeout) {
//defining the promised based API
var deffered = $q.defer();
//the getData function
var getData = function() {
//defining a empty data array
var theData = {};
//using $http to get the dat
$http.get('/wordpress/api/get_recent_posts/').success(function(data) {
// prepare data here
//assigning our data to the theData array.
// // New stuff here, we are pushing the data one by one to populate the array faster so it isn't emtpy .. ?!
theData.length = 0;
for (var i = 0; i < data.length; i++) {
theData.push(data[i]);
}
theData = data;
});
//setting a timeout for the data and waiting if necesarry.
$timeout(function() {
deffered.resolve(theData);
}, 1000);
//when it s done, return the promise... i think so. ?!
return deffered.promise;
}
return {
//creating a getData handler to use in controllers.
getData: getData
};
}])
我正在使用getData().then()在加载时获取它
我意识到我没有对过滤器说同样的话
angular.module('filters', [])
.filter('checkboxFilter', function($filter) {
return function(post, prefs) {
var i, j, k, n, out, matchingpost = [];
// loop through the post
for (i = 0; i < post.length; i++) {
console.log('I passed the length ... wtf?')
out = false;
n = 0;
if (prefs) {
// for each item, loop through the checkboxes categories
for (j = 0; j < prefs.length; j++) {
// for each category, loop through the checkboxes categories of the current category
for (k = 0; k < prefs[j].categories.length; k++) {
// test if the current item property name is the same as the filter name
if (post[i][prefs[j].slug] === prefs[j].categories[k].slug) {
// test if checkbox is checked for this property
(prefs[j].categories[k].value) ? n++ : out = true;
break;
}
}
if (out) break;
// if one filter in each categories is true, add item to the matchingpost
if (n === prefs.length) {
matchingpost.push(post[i]);
}
}
}
}
return matchingpost;
}
})
angular.module('filters',[])
.filter('checkboxFilter',函数($filter){
返回函数(post、prefs){
变量i,j,k,n,out,matchingpost=[];
//在柱子上绕圈子
对于(i=0;i
问题是我开始读一本有棱角的书,但我不懂很多东西,所以我开始亲身体验,慢慢地每一点都到位了,但这一点。。。我花了很多时间在这上面。我想如果我再接下去,会更有意义
问题:如何消除这些错误并使筛选器在加载数据后读取数据
附带问题:通过一个不同的服务,我输出我主干网(Wordpress)中的所有现有类别,并在复选框中重复它们,我将如何将复选框链接到此过滤器的结果?(这对我来说还不明显,尽管我已经看到了一些例子……)
旁白2:为什么我所有的请求都会成倍增加,就像我发布的第一个屏幕截图一样,不,等等,这就是我要说的部分。。。到目前为止,我只有44篇帖子,但看起来即使数据已经存在,过滤器也会再次调用它 这种行为也发生在其他事情上。。。我想知道我做错了什么
注释:我正在使用angular 1.2.0rc1,从今晚开始,所有行为都出现在我使用的其他版本中:1.0.7.0、1.1.5
//defining a empty data array
var theData = {};
这是一个对象定义,不是数组定义。试着用
var theData = [];
这可能会解决您的问题。无需创建您自己的承诺,因为AngularJS
$http
服务已经为您提供了这一功能
因此,您的服务可以简化为:
angular.module('services', []).factory('getAllPosts', ['$http', function($http) {
return {
getData: function() {
// Return the promise that is created by the $http service
return $http.get('/wordpress/api/get_recent_posts/')
}
};
}]);
<li ng-repeat="item in items">
{{item.someProperty}}
</li>
然后在控制器中:
angular.module('yourModule')
.controller('ListController', ['$scope', 'getAllPosts',
function($scope, getAllPosts) {
$scope.items = []; // Placeholder for the data
getAllPosts.getData()
.success(function(data, status, header, config){
// Fill placeholder with data as soon as it is received
$scope.items = data;
});
}
]);
然后在您的视图中,您可以使用ng model
指令或ng repeat
指令如下所示显示数据:
angular.module('services', []).factory('getAllPosts', ['$http', function($http) {
return {
getData: function() {
// Return the promise that is created by the $http service
return $http.get('/wordpress/api/get_recent_posts/')
}
};
}]);
<li ng-repeat="item in items">
{{item.someProperty}}
</li>
{{item.someProperty}
如果要应用自定义筛选器,只需使用:
<li ng-repeat="item in items | your_filter">
{{item.someProperty}}
</li>
{{item.someProperty}
AngularJS将在更新$scope.items
时自动更新视图,因此您无需为此编写额外的代码
希望有帮助 解决这个问题的方法似乎是在信息到达之前循环。任何其他解决方案都是受欢迎的 像这样:
.filter('checkboxFilter', function() {
return function(post, prefs) {
//define empty vars, strict mode
var i, j, k, n, out, matchingpost = [];
//check to see if the posts have arrived
if (post == undefined) {
//posts are not here yet
} else {
//posts have arrived.
//iterate through all the posts
for (i = 0; i < post.length; i++) {
out = false;
n = 0;
var eachPostCategories = post[i].categories;
//console.log(eachPostCategories)
for (j = 0; j < eachPostCategories.length; j++) {
//console.log(' post categories are');
//console.log(eachPostCategories[j]);
if (prefs == undefined) {
//preferences aren't in yet
} else {
//preferences are here.
//now we should iterate through all the preferences and compare them to the posts.
for (k = 0; k < prefs.length; k++) {
//prefs[j].slug
//console.log('categories are');
//console.log(prefs[k].slug)
if (eachPostCategories[j].slug === prefs[k].slug) {
//console.log('this post has the categories');
//console.log(post[i]);
//WHAT DOES THIS LINE MEAN?
/*(prefs[k].slug) ? n++ : out = true;
break;*/
n++
} else {
out = true;
break;
}
console.log('n is ' + n);
}
if (out) break;
// if one filter in each categories is true, add item to the matchingpost
if (n === prefs.length) {
matchingpost.push(post[i]);
}
}
}
}
}
if (matchingpost.length == 0) {
//return matchingpost = post
} else {
return matchingpost;
}
}
})
要发布具有多个类别的对象(例如,后期缩放的房屋具有日期、建筑类别)我认为真正的方法是覆盖默认的
$interpolateProvider
,以启用返回承诺的过滤器。这样,您就可以推迟某些过滤表达式的呈现,直到它们被解析
但是,请记住,对于链式过滤器,您不能简单地执行此操作。您可能还将被迫重写$parse
,以支持承诺链
我现在面临着同样的问题,因此,我可能会继续这样做。如果是这样,我将确保在github存储库中为我的项目()发布一个指向答案的链接
编辑
另一种(大部分)简单的方法是将任意参数传递给过滤器,并通过HTTP调用(或任何其他方式)进行更新:
在这里,我刚刚通过超时更新了结果,但我不必这样做。这只是为了示范。您可以选择任何方式更新$scope.result
这是一个示例过滤器,它只会在结果中包含偶数:
.filter('even', function () {
return function (input) {
if (!angular.isArray(input)) {
return input;
}
var result = [];
angular.forEach(input, function (x) {
if (x % 2 == 0) {
result.push(x);
}
});
return result;
}
});
现在,在我看来,我可以通过以下方式将它们结合使用:
<div ng-controller="MyController">
<ul ng-if="result.length"> <!-- It is nice to not pollute the DOM with empty lists -->
<li ng-repeat="item in result | even">{{item}}</li>
</ul>
</div>
<div ng-controller="MyController">
<ul ng-if="result.length"> <!-- It is nice to not pollute the DOM with empty lists -->
<li ng-repeat="item in result | even">{{item}}</li>
</ul>
</div>
app.filter('translate', function() {
return function(input) {
try {
var index = input.toUpperCase();
if (app.translation[index]) {
if (input[0] === index[0])
return app.translation[index].capitalize();
return app.translation[index];
}
return input;
}
catch(err) {
throw "Translation not loaded yet, trying again...";
}
};
})
app.run(function($http) {
$http.get("translations/" + "NB_ENG" + ".json", {
cache: true
}).success(function(data) {
app.translation = data;
console.info("Translation loaded.");
}).error(function(q,w,e) {
app.translation = 1;
console.error("Failed getting translation: "+q + " | " + w + " | " + e + " | ");
});
});