У меня есть служба Angular, которая обрабатывает перевод через вызов моего веб-интерфейса 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: Вы можете найти полный код услуги здесь (только скрипт), чтобы быть полным.
Вы назначаете обещание своему тексту, поэтому он не работает...
Перевод исходит из 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: асинхронно инициализировать фильтр
Существует также сторонний плагин под названием 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;
}
В ответ на 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
.
var text = $filter('translate')('dateOfBirth', 'FR')