我有一个Angular服务,通过调用我的Web API后端来处理翻译,如下所示:
self.Translate = function (languageCode, keyword) {
var defer = $q.defer();
var uri = "api/translation/translate/" + languageCode + "/" + keyword;
apiService.Get(uri).then(function (translation) {
defer.resolve(translation.Text);
}, function (error) {
var msg = "Unable to translate keyword '" + keyword + "' for language code '" + languageCode + "'. Make sure that you can connect to the Web API and that the requested translation exists.";
loggerService.Error(self.Name, msg);
defer.reject(msg);
});
return defer.promise;
}
它被称为:
var text = translationService.Translate("FR", "dateOfBirth");
哪会回来:
date de naissance
然而,在接收端我得到了这个(在console.log中):
d {$$state: Object}
$$state: Object
status: 1
value: "date de naissance"
__proto__: Object
__proto__: d
显示[object Object]
的结果,而不是翻译文本。
基于以上所述,您会认为以下内容可行:
var text = translationService.Translate("FR", dateOfBirth).value;
但事实并非如此,它会返回undefined
。
知道发生了什么以及如何解决这个问题?谢谢!
PS:您可以找到完整的服务代码here(仅限脚本)。
答案 0 :(得分:1)
您正在为自己的文字分配承诺,这就是为什么它不起作用......
转换来自API,因此您需要在从服务器请求数据时处理该情况,然后在API返回时进行更新。
您的翻译功能在功能上是正确的,但我建议您更改为此格式作为最佳做法。
self.Translate = function (languageCode, keyword) {
var uri = "api/translation/translate/" + languageCode + "/" + keyword;
return apiService.Get(uri).then(function (translation) {
return translation.Text;
}, function (error) {
var msg = "Unable to translate keyword '" + keyword + "' for language code '" + languageCode + "'. Make sure that you can connect to the Web API and that the requested translation exists.";
loggerService.Error(self.Name, msg);
return $q.reject(msg);
});
}
调用部分应该是这样的:
var text = '';
translationService.Translate("FR", dateOfBirth).then(function(data){
text = data;
// any logic before assigning text to scope variable should be done here
});
这是典型的异步承诺处理。一开始可能看起来很奇怪,但你会习惯它。
如果您坚持使用var text = ??
表单,则可以创建过滤器。您可以参考AngularJS : Asynchronously initialize filter
还有一个名为angular-translate的第三方插件支持使用过滤器,也许你也可以参考他们的代码。
更新:显示案例承诺链接
self.GetMeaningfulTitle = function (options) {
var defer = $q.defer();
translationService.Translate(options.Language, "Edit").then(function(translation) {
personService.Get(options.PersonId).then(function(person){
var result = "";
if (personValidatorService.Validate(person) {
result = translation + " - " + person.Firstname + " " person.Lastname;
defer.resolve(result);
}else{
defer.reject("Invalid person detected");
}
}
});
return defer.promise;
}
答案 1 :(得分:0)
根据提供的链接回应Icycool:
这(部分)有效:
angular.module("filters.webapi")
.filter("translate", [
"translationService",
function (translationService) {
var data = null;
var serviceInvoked = false;
// real filter
function realFilter(keyword, languageCode) {
return data;
}
// Async wait filter
filterStub.$stateful = true;
function filterStub(keyword, languageCode) {
if (data === null) {
if (!serviceInvoked) {
serviceInvoked = true;
translationService.Translate(languageCode, keyword).then(
function(translation) {
data = translation;
}, function(error) {
data = keyword;
});
}
return "";
} else {
return realFilter(keyword, languageCode);
}
}
return filterStub;
}
]);
如果在html中使用如下:
{{ "dateOfBirth" | translate:Language }}
但我如何在脚本中使用它?
我的意思是,等同于:
var text = translationService.Translate("FR", "dateOfBirth")
<强> 更新 强>
每个请求的示例用法(极简化):
self.GetMeaningfulTitle = function (options) {
var defer = $q.defer();
personService.Get(options.PersonId).then(function(person){
var result = "";
var action = $filter("translate")("Edit", options.Language);
if (personValidatorService.Validate(person) {
result = action + " - " + person.Firstname + " " person.Lastname;
defer.resolve(result);
}else{
defer.reject("Invalid person detected");
}
}
return defer.promise;
}
假设此人信息有效,则会产生- Firstname Lastname
。