最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use a promise inside an object literal - Stack Overflow

programmeradmin2浏览0评论

In angular-translate version 2.0 the $translate service no longer returns the actual translation but a promise. I can see that is a good idea because there could be some asynchronous loading going on. But it confuses me how to use the service properly in my case, because I used the $translate service inside an object literal, like this

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

Question: How do I use a promise inside an object literal?

It is supposed to (according to the documentation) be used like this:

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

In angular-translate version 2.0 the $translate service no longer returns the actual translation but a promise. I can see that is a good idea because there could be some asynchronous loading going on. But it confuses me how to use the service properly in my case, because I used the $translate service inside an object literal, like this

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

Question: How do I use a promise inside an object literal?

It is supposed to (according to the documentation) be used like this:

$translate('HEADLINE').then(function (headline) {
    $scope.headline = headline;
});
Share Improve this question edited Feb 23, 2014 at 23:01 swenedo asked Feb 23, 2014 at 22:54 swenedoswenedo 3,1149 gold badges32 silver badges50 bronze badges 1
  • I wish you could "follow" a question on SO without necessarily marking it as a favorite. or... "notify when accepted". I know there's a super slick way to do this, but it's Sunday evening and my brain won't re-engage properly. I do like @calebboyd's answer below, but something tells me there's a way to create a custom service to do what you want... which is sorta what he did, just not abstracted to the service layer. – Brian Vanderbusch Commented Feb 24, 2014 at 0:45
Add a comment  | 

4 Answers 4

Reset to default 14

If you know that there's no asynchronous stuff going on, you can use $translate.instant() which behaves exactly like $translate() in 1.x.

You'd need to have a direct reference. Or a helper function that has closure over the reference. Like:

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

]

and elsewhere

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

Update

as Brian suggested below, Its always a good idea to write generic code you can use all over.

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

So you can use it like...

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

If you re using ui-grid, solution is to add headerCellFilter: 'translate' to columnsDefs (means myDefs) and displayName must have translation key.

Here is,

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

Another idea is to loop through your literal and replace all the promises with values. However I don't know what happens if you call then, when a promise has already been resolved.

angular.forEach($scope.myDefs, function(element){
   element.displayName.then(function(result){
      element.displayName= result;
   })
})
发布评论

评论列表(0)

  1. 暂无评论