问题 按翻译的值对ng-options进行排序


使用angular-translate翻译选择选项真的很容易:

<select name="languageId"
  ng-options="p.id as ('LANGUAGE.'+p.id)|translate for p in Const.languages | orderBy:'name'">

但是这样,选项按原始键排序,而不是翻译。 有没有办法可以按照他们的顺序排列该列表 翻译 没有在控制器中预先准备该列表的值?


3610
2017-07-23 11:27


起源

嘿@hoeni,你找到了解决方案吗?如果是的话,你是怎么做到的?我也有同样的问题。 - Magda
没有好的解决方案,但是:-(我正在准备控制器中的列表,以保持性能可接受。 - hoeni
我的解决方案不适合你吗? - Betty St
@Betty它并不完美,因为每次改变时它都会重新翻译。但到目前为止仍然是最好的;-) - hoeni
对不起,我不能给@stefitz提供不止一票的答案,因为它比其他所有人都简单得多。这应该是公认的答案。 - Dag Høidahl


答案:


对我来说最简单的方法(角度1.2.24和角度转换2.14.0):

<select name="nationality" ng-model="person.nationality" ng-options="c.id as c.name | translate for c in Const.countries | orderBy:'name | translate' ">

这个评论的作者可以归功于此: https://github.com/angular-translate/angular-translate/issues/1064#issuecomment-267357441


5
2018-02-22 07:21



这是正确的答案! - claywhipkey


您可以提供谓词函数 orderBy 并让该函数返回翻译的值。这意味着你也必须通过 $filter 因为你需要调用你的控制器服务 translate 在你的JS代码中。

所以,提供一些代码作为指导:

// CONTROLLER
// * Don't forget to inject the $filter service

$scope.translated = function(p) {
    return $filter('translate')('LANGUAGE.' + p.id);
}

然后你会修改你的 orderBy 表达:

... | orderBy:translated

我意识到这个建议似乎有点费解,因为一次翻译尝试发生在 ng-options 然后是另一个 orderBy,但它应该排序 select 你期望的选择。


3
2017-10-20 07:14



如何将orderBy中的参数传递给翻译?因为我正在尝试你的方法,但它不起作用,我也尝试了orderBy:translated(p)。谢谢 - davidivad
当前项隐式传递给谓词函数。您不需要通过HTML明确地这样做(即只需要函数名就足够了)。只需确保谓词函数定义只需一个参数即可。 - miqh


我有同样的问题,我建议使用自己的过滤器,因为你不想搞砸你的控制器!这是我目前的解决方案:

/**
 * orderByTranslated Filter
 * Sort ng-options or ng-repeat by translated values
 * @example
 *   ng-options="country as ('countries.'+country | translate) for country in countries | orderByTranslated:'countries.'"
 * @param  {Array} array
 * @param  {String} i18nKeyPrefix
 * @param  {String} objKey
 * @return {Array}
 */
app.filter('orderByTranslated', ['$translate', '$filter', function($translate, $filter) {
  return function(array, i18nKeyPrefix, objKey) {
    var result = [];
    var translated = [];
    angular.forEach(array, function(value) {
      var i18nKeySuffix = objKey ? value[objKey] : value;
      translated.push({
        key: value,
        label: $translate.instant(i18nKeyPrefix + i18nKeySuffix)
      });
    });
    angular.forEach($filter('orderBy')(translated, 'label'), function(sortedObject) {
      result.push(sortedObject.key);
    });
    return result;
  };
}]);

注意 你需要传递你的i18n前缀'LANGUAGE'。我看到你使用一个对象而不是一个简单的字符串数组,所以你可以像这样使用它:

<select name="languageId"
  ng-options="p.id as ('LANGUAGE.'+p.id)|translate for p in Const.languages | orderByTranslated:'LANGUAGE.':'id'">

3
2017-12-02 14:24



我建议检查objKey是否未定义,并在这种情况下使用前缀作为objKey。通过这种修改,也可以使用没有前缀的过滤器。 - Dirk
嗯我不明白?使用此解决方案,它适用于数组和对象 - Betty St


我知道这是一个老问题,但今天偶然发现了这个问题,在这种情况下你可以解决它(仅适用于 Array 虽然):

<select name="languageId"
  ng-options="p.id as name=('LANGUAGE.'+p.id)|translate for p in Const.languages | orderBy:'name'">

诀窍是分配翻译并使用此分配进行排序。


2
2018-05-25 04:18