2014-03-24 33 views
1

我正在使用一個Angular工廠,它從Feed中檢索數據並對其執行一些數據操作。Angular:重寫函數以使用promise

我想阻止我的應用程序渲染第一個視圖,直到完成數據準備。我的理解是我需要爲此使用promise,然後在控制器中使用。然後調用可以在承諾解決後立即運行的函數。

從看atexamples我發現很難在我的工廠實施承諾。具體而言,我不確定將推遲和解決方案放在哪裏。任何人都可以權衡什麼是最好的實現方法?

這裏是不承諾我工作的工廠:

angular.module('MyApp.DataHandler', []) // So Modular, much name 

.factory('DataHandler', function ($rootScope, $state, StorageHandler) { 

    var obj = { 

    InitData : function() { 

     StorageHandler.defaultConfig = {clientName:'test_feed'}; 
     StorageHandler.prepData = function(data) { 
     var i = 0; 
     var maps = StorageHandler.dataMap; 

     i = data.line_up.length; 
     while(i--) { 
     // Do loads of string manipulations here 
     } 
     return data; 
     } 

     // Check for localdata 
     if(typeof StorageHandler.handle('localdata.favorites') == 'undefined') { 
     StorageHandler.handle('localdata.favorites',[]); 
     } 

    }, 

    }; 
    return obj; 

}); 

這是我從看例子嘗試:

angular.module('MyApp.DataHandler', []) // So Modular, much name 

.factory('DataHandler', function ($rootScope, $q, $state, StorageHandler) { 

    var obj = { 

    InitData : function() { 

     var d = $q.defer(); // Set defer 

     StorageHandler.defaultConfig = {clientName:'test_feed'}; 
     StorageHandler.prepData = function(data) { 
     var i = 0; 
     var maps = StorageHandler.dataMap; 

     i = data.line_up.length; 
     while(i--) { 
     // Do loads of string manipulations here 
     } 
     return data; 
     } 

     // Check for localdata 
     if(typeof StorageHandler.handle('localdata.favorites') == 'undefined') { 
     StorageHandler.handle('localdata.favorites',[]); 
     } 
     return d.promise; // Return promise 
    }, 

    }; 
    return obj; 

}); 

但沒有什麼是在控制檯中顯示,當我用這個在我的控制器:

DataHandler.InitData() 
.then(function() { 
    // Successful 
    console.log('success'); 
}, 
function() { 
    // failure 
    console.log('failure'); 
}) 
.then(function() { 
    // Like a Finally Clause 
    console.log('done'); 
}); 

有什麼想法?

+2

哪裏是你的'd.resolve()'?看來你沒有執行任何操作。 –

+1

你也不會在任何地方撥打'prepData' –

回答

1

像弗洛裏安提到的。您的異步調用在您顯示的代碼中並不明顯。

這裏是你想要的要點是:

angular.module("myApp",[]).factory("myFactory",function($http,$q){ 
    return { 
    //$http.get returns a promise. 
    //which is latched onto and chained in the controller 
    initData: function(){ 
     return $http.get("myurl").then(function(response){ 
     var data = response.data; 
     //Do All your things... 
     return data; 
     },function(err){ 
     //do stuff with the error.. 
     return $q.reject(err); 
     //OR throw err; 
     //as mentioned below returning a new rejected promise is a slight anti-pattern, 
     //However, a practical use case could be that it would suppress logging, 
     //and allow specific throw/logging control where the service is implemented (controller)    
    }); 
    } 
    } 
}).controller("myCtrl",function(myFactory,$scope){ 
    myFactory.initData().then(function(data){ 
    $scope.myData = data; 
    },function(err){ 
    //error loudly 
    $scope.error = err.message 
    })['finally'](function(){ 
    //done. 
    }); 
}); 
+0

感謝@calebboyd,會盡力實現這一點。正如你所提到的,它需要一些重構來實現這一點。 – Squrler

+2

@calebboyd返回明確的拒絕是一種反模式。你應該總是喜歡'拋出'就像你在同步代碼中一樣。鏈接繼續與拋出安全是無論如何承諾的一個重要的基本部分。 –

+0

然後你應該取代[docs](http://docs.angularjs.org/api/ng/service/$q#reject)。因爲他們促進了這種反模式。 – calebboyd