AngularJS: вызов службы перевода возвращает непригодный объект состояния $$

0

У меня есть служба 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: Вы можете найти полный код услуги здесь (только скрипт), чтобы быть полным.

Теги:
asp.net-mvc

2 ответа

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: асинхронно инициализировать фильтр

Существует также сторонний плагин под названием 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;
}
  • 0
    Спасибо за информацию, но я не вижу никакой разницы. Я знаю angular-translate и нашел его очень ненадежным, например, переводы не работают при загрузке первой страницы (и это проблема, так как я использую SPA).
  • 0
    Не видите никакой разницы? Вы имеете в виду, что после изменения кода вы получаете ту же ошибку? Это нормально для SPA, чтобы иметь начальное состояние и завершенное состояние после всех необходимых возвращений ajax.
Показать ещё 2 комментария
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.

  • 1
    var text = $filter('translate')('dateOfBirth', 'FR')
  • 0
    Хорошо, мы добираемся туда, но это не работает (оно остается значением заполнителя), когда используется в функции, которая возвращает обещание. Работает нормально в не асинхронной функции.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню