2014-02-23 2 views
5

В angular-translate версии 2.0 $translate service больше не возвращает фактический перевод, а обещание. Я вижу, что это хорошая идея, потому что может произойти асинхронная загрузка. Но меня смущает, как использовать службу должным образом в моем случае, потому что я использовал $ перевести службу внутри литерала объекта, как этотКак использовать обещание внутри объекта литерал

$scope.myDefs = [ 
     ... 
     { 
      field: 'supplier', 
      displayName: $translate('Supplier'), 
      cellTemplate: "<div class=\"ngCellText\">...</div>" 
     }, 
     ... 
     { 
      field: 'supplierSize', 
      displayName: $translate('Size'), 
      width: 100, 
      cellClass: "center" 
     } 
     ... 
]; 

Вопрос: Как использовать обещание внутри объекта буквальным?

Предполагается (в соответствии с documentation) можно использовать следующим образом:

$translate('HEADLINE').then(function (headline) { 
    $scope.headline = headline; 
}); 
+0

Я желаю вам может "следовать" вопрос о SO без необходимости пометив его как фаворита. или ... «уведомлять, когда принимаются». Я знаю, что есть супер-гладкий способ сделать это, но это воскресный вечер, и мой мозг не будет снова подключаться должным образом. Мне нравится следующий ответ @ calebboyd, но что-то говорит мне, что есть способ создать настраиваемую службу, чтобы делать то, что вы хотите ... что это то, что он сделал, просто не абстрагировался до уровня сервиса. –

ответ

6

Вам нужно будет иметь прямую ссылку. Или вспомогательная функция, которая имеет замыкание по ссылке. Как:

$scope.myDefs = [ 
    ... 
    createArrayObject({ 
     field: 'supplier', 
     displayName: $translate('Supplier'), 
     cellTemplate: "<div class=\"ngCellText\">...</div>"   
    }), 
    createArrayObject(..... 

] 

и других

function createArrayObject(obj){ 
    obj.displayName.then(function(data){ 
     obj.displayName = data; 
    }); 
    return obj; 
} 

Update

Брайан предложил ниже, его всегда хорошая идея, чтобы написать общий код, который можно использовать во всем.

var forEach = angular.forEach, 
    isFunction = angular.isFunction; 

function resolveProperties(obj){ 
    forEach(obj,function(val,key){ 
     if(isFunction(val.then)){ 
      val.then(function(data){ 
       obj[key] = data; 
      }); 
     } 
    }); 
} 

Таким образом, вы можете использовать его как ...

[ 
    resolveProperties({ 
     myPropertyToResolve: promiseReturningFunction() 
    }), 
    .... 
] 
+0

вы можете просто ссылаться на текущий контекстный контекст объекта внутри «then» с «this». – iSchluff

+0

myDefs должен быть массивом, я использую его с сторонней библиотекой, а 'this' не определено ... – swenedo

+0

oh right, но тогда нет никакой пользы от вызова функции в литерале объекта, потому что вы не возвращая что-нибудь – iSchluff

0

Другая идея состоит в том, чтобы перебрать ваш буквальным и заменить все обещания со значениями. Однако я не знаю, что произойдет, если вы позвоните тогда, когда обещание уже разрешено.

angular.forEach($scope.myDefs, function(element){ 
    element.displayName.then(function(result){ 
     element.displayName= result; 
    }) 
}) 
14

Если вы знаете, что нет никакого асинхронным вещей происходит, вы можете использовать $translate.instant(), которая ведет себя так же, как $translate() в 1.x.

2

Если вы используете ui-grid, решение состоит в том, чтобы добавить headerCellFilter: 'translate' to columnsDefs (означает myDefs) и displayName должен иметь ключ перевода.

Вот,

$scope.myDefs = [ 
 
     { 
 
      field: 'supplier', 
 
      displayName: "Supplier", 
 
      cellTemplate: "<div class=\"ngCellText\">...</div>", 
 
      headerCellFilter: 'translate' 
 
     }, 
 
     { 
 
      field: 'supplierSize', 
 
      displayName: "Size", 
 
      width: 100, 
 
      cellClass: "center", 
 
      headerCellFilter: 'translate' 
 
     } 
 
];

Смежные вопросы