2015-10-28 61 views
0

我有通过调用句柄翻译我的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(仅限脚本)。

回答

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 
}); 

这是典型的asynchronus承诺处理。它可能起初看起来很奇怪,但你会习惯它。

如果你坚持var text = ??的形式,你可以创建一个过滤器。你可以参考AngularJS : Asynchronously initialize filter

还有一个名为angular-translate的第三方插件支持使用过滤器,也许你也可以参考他们的代码。如果使用

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; 
     } 
    ]); 


更新:展会情况下诺言链

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

感谢您的信息,但我没有看到任何区别。我知道角度翻译,发现它非常不可靠,翻译等不起作用的第一页加载(这是一个问题,因为我使用SPA)。 – Spikee

+0

看不到有什么区别?你的意思是在改变代码后你会得到相同的错误?在所有需要ajax回报后,SPA有初始状态和完整状态是正常的。 – Icycool

+0

因为您正在为每个关键字点击服务器,而角度翻译一次为语言加载一次,所以您应该观察到比使用当前代码的角度转换性能更差的性能。 – Icycool

0

针对Icycool,根据提供的链接:

这(部分)工程像这样在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')' – Icycool

+0

好的,我们到了那里,但它在用于返回承诺的函数中时不起作用(它仍然是占位符值)。在非异步功能中正常工作。 – Spikee

+0

你能举例说明代码吗? – Icycool