我有一段经常使用的代码片段,它调用API以便根据发送给它的ID返回用户名。
GetUserNames.get({users: user}, function (data) {
$scope.userName = data[0];
})
我想做的是把它变成一个过滤器,我可以做一些像
这样的事情{{userID | returnUserName}}
这样我就可以重复使用并保持控制器和视图的清洁。我写了这样的话:
angular.module('app.filters').filter('returnUserName', function(GetUserNames) {
return function(input) {
GetUserNames.get({ users: input }, function (data) {
console.log(data[0])
return data[0]
});
}
});
当console.log返回正确的值时,我在页面上看不到它。我猜这是一个时间问题。我可以做些什么来使这项工作,然后在页面上填充值?
答案 0 :(得分:3)
我有一段经常使用的代码片段
每当你听到自己说认为服务不过滤时。虽然理论上你 可以让你的过滤器进行远程调用,但是过度使用过滤器可能会非常低效(可能导致你的页面变慢,甚至可能使你的服务器DDoS)。
您的模式应该更像
{{ returnUserName(userId) }}
或者甚至可能在某处预先计算机用户名,然后再做
{{ userName }}
答案 1 :(得分:1)
只是回答你的问题,这里有一段应该回答你问题的代码片段。 如果你使用Angular 1.3.X,你可以使用$ stateful like:
angular.module('app.filters').filter('returnUserName', function($http) {
var data = null, serviceInvoked = false;
function realFilter(value) {
return data;
}
filterStub.$stateful = true;
function filterStub(value) {
if( data === null ) {
if( !serviceInvoked ) {
serviceInvoked = true;
$http.get('/url/test/').then(function (res) {
data = res;
});
}
return "";
}
else return realFilter(value);
}
return filterStub;
});
有关详细信息:here
我希望它会帮助你。
答案 2 :(得分:0)
正如@Florian Orpeliere所提到的,您可以使用有状态过滤器 - 另外使用一些缓存变量:
angular.module("app").filter('svcData', function($http) {
var cached = {};
var apiUrl = 'http://my.service.com';
function svcDataFilter(data_id, data_prop) {
if (data_id) {
if (data_id in cached) {
// avoid returning a promise!
return typeof cached[data_id].then !== 'function' ?
cached[data_id][data_prop] : undefined;
} else {
cached[data_id] = $http({
method: 'GET',
url: apiUrl + data_id
}).success(function (data) {
cached[data_id] = data;
});
}
}
}
svcDataFilterFilter.$stateful = true;
return svcDataFilterFilter;
})
并像这样使用它:{{data_id |svcData:'property'}}
注意:将在每个摘要周期上调用函数svcDataFilter。
此外,如果缓存增长过大,您需要找到一种方法来重置缓存。
请参阅:https://glebbahmutov.com/blog/async-angular-filter/
并且上面的链接(上面的链接不会显示它,所以这里是直接链接):http://plnkr.co/edit/EK2TYI1NZevojOFDpaOG?p=preview