更新时间:2023-11-01 21:08:28
我认为你不应该那样使用过滤器.过滤器用于根据可选参数转换输入.
这里的问题是您立即从过滤器函数返回了一个承诺.而这是 Angular 无法通过过滤器处理的结果.
因此,我的建议是 - 首先获取结果,然后根据结果使用过滤器:
var app = angular.module("my.module");app.controller("MyCtrl", ['$http', '$scope', function(http, scope) {scope.hello = "foo";http.get('http://my.service.com').then(function(data) {scope.filterParams = 数据;}, 函数(错误){scope.filterParams = 未定义;});}]);app.filter("filterHello", function() {返回函数(输入,参数){if(typeof params === "未定义") {返回 "";}//处理这里的参数};});
并在模板中:
{{hello|filterHello:filterParams}}
只需阅读您的解释.对我来说,这将是指令的候选:
app.directive("companyName", ['$http', function(http) {返回 {模板:<span>{{name}}</span>",范围: {公司 ID:="},链接:功能(范围){http.get("http://my.service.com/companies/" + scope.id).then(function(result) {范围.名称 = 结果.名称;}, 函数(错误){scope.name = "未知";});}}}]);
并在模板中:
<span company-name company-id="user.company_id"></span>
如果您有很多公司,您应该预先加载名称(也许最初将它们与第一个响应一起发送?),因为您会用请求轰炸您的服务器.
I would like to do a request to my backend in a filter and return the result of my request. The problem is the service $http return a promise and it's the issue.
For present the issue I used a $timeout and the promises of angular in my fiddle : my fiddle
In my filter I use a $timeout with a promise but the final goal is to use a request http :
myApp.filter('filterHello', function ($http,$timeout,$q) {
return function (company_id) {
console.log("in the filter");
var deferred = $q.defer();
$timeout(function() {
deferred.resolve("ca marche");
}, 2000);
return deferred.promise;
};
});
Then in my view I use my filter who is suppose to display "ca marche" with a delay of 2 secondes but that doesn't work :
<div ng-controller="MyCtrl">
{{hello|filterHello}}
</div>
You can see that the filter return nothing and that there is an infinite loop in the filter because of the null promise I think.
If you don't understand why I want use a request http in a filter the answer is simple. For exemple I have an object user with the fields : email,name,company_id.. And I have an other object company with the fields : name, createOn,... I would like use the filter like this for display the name of the user's company :
{{user.company_id | ShowNameCompany}}
So, I need to do a request http in the filter to my company controller of my backend.
I hope someone can help me.
I think you should not use filters that way. Filters are for transforming inputs based on optional params.
The problem here would be that you're immediately returning a promise from the filter function. And that's nothing Angular can deal with as a result from a filter.
My suggestion therefore would be this - fetch the result first, work with the filter based on the result:
var app = angular.module("my.module");
app.controller("MyCtrl", ['$http', '$scope', function(http, scope) {
scope.hello = "foo";
http.get('http://my.service.com').then(function(data) {
scope.filterParams = data;
}, function(err) {
scope.filterParams = undefined;
});
}]);
app.filter("filterHello", function() {
return function(input, params) {
if(typeof params === "undefined") {
return "";
}
//work with the params here
};
});
and in the Template:
<div ng-controller="MyCtrl">
{{hello|filterHello:filterParams}}
</div>
Edit: Just read your explanation. To me, this would be a candidate for a directive:
app.directive("companyName", ['$http', function(http) {
return {
template: "<span>{{name}}</span>",
scope: {
companyId: "="
},
link: function(scope) {
http.get("http://my.service.com/companies/" + scope.id).then(function(result) {
scope.name = result.name;
}, function(err) {
scope.name = "unknown";
});
}
}
}]);
and in the template:
<span company-name company-id="user.company_id"></span>
If you have a lot of companies, you should preload the names (maybe send them with the first response initially?), as you'd be bombarding your server quite a bit with requests.