AngularJS:转换服务调用返回不可用的$$状态对象

时间:2015-10-28 07:05:22

标签: javascript c# angularjs asp.net-mvc

我有一个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(仅限脚本)。

2 个答案:

答案 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