2015-04-27 93 views
2
var app = angular.module('app',['ui.bootstrap']); 

app.controller("ListCtrl", function ($scope, $http) { 

    $scope.submit = function() { 
     $scope.loading = true; 
     $scope.error = false; 
     $http.get('http://www.omdbapi.com/?s=' + $scope.search + '&r=json') 
       .then(function (res) { 
        var titles = []; 
        angular.forEach(res.data.Search, function(item){ 
         $http.get('http://www.omdbapi.com/?t=' + item.Title + '&y=&plot=full&r=json').then(function(res){ 
         if (res.data.Poster === "N/A") { 
         res.data.Poster = "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!"; 
         } 
         titles.push(res.data); 
         }); 
        }); 

        $scope.movie = titles; 
        $scope.results = true; 
        $scope.error = false; 
        $scope.loading = false; 


        if (titles.length==0) {   // not working 
         $scope.results = false; 
         $scope.error = true; 
        } 


       }) 

我都試過了幾件事情,如:如何檢查對象數組是否爲空?

Object.getOwnPropertyNames(titles).length === 0) 
obj == null 

他們都不似乎工作...這樣的語句if (titles.length==0) {被馬上執行

+1

任何工作樣本? – Vijay

+0

你可以調試並檢查長度是否真的爲零! – Vishwanath

回答

0

$http.get()是異步。

有一個計數器來確定何時所有的承諾解決,然後執行檢查。在回調中移動if語句。

var count = res.data.Search.length; 

angular.forEach(res.data.Search, function(item){ 
    $http.get('http://www.o....rest of code').then(function(res) { 
     // rest of code 

     titles.push(res.data); 
     if (!count-- && !titles.length) { 
      $scope.results = false; 
      $scope.error = true; 
     } 
     } 
    }); 
}); 
+1

謝謝,它工作完美! –

2

發生這種情況,因爲不正確範圍

var titles = [];.then

內部定義的,你正在檢查外.then

因爲titles不可外的長度.then它不會工作。 (undefined.length==0

解決方案:

.then(function (res) { 
        var titles = []; 
        angular.forEach(res.data.Search, function(item){ 
         $http.get('http://www.omdbapi.com/?t=' + item.Title + '&y=&plot=full&r=json').then(function(res){ 
         if (res.data.Poster === "N/A") { 
         res.data.Poster = "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!"; 
         } 
         titles.push(res.data); 
         }); 
       $scope.movie = titles; 
       $scope.results = true; 
       $scope.error = false; 
       $scope.loading = false; 


       if (titles.length==0) {   // now this will work 
        $scope.results = false; 
        $scope.error = true; 
       } 
    });//titles will not be available after this. 
0

在你的情況,檢查

titles.length 

將前

titles.push 

,因爲您使用的異步請求可以被執行,稍後會返回。 您需要將您的語句包裝到請求的答案塊中。

0

正如順便說一句,但對我的做法和你的未來的幫助是有益的:

部分你有餘地管理(JS-範圍,沒有棱角$範圍)的問題,它的一部分是併發管理,而且它的一部分似乎是普通的舊範圍格式,使得很難看到所有控制塊的開始和結束位置(當它不僅僅是if/else,而且還有回調/承諾時,它變得很悲慘)。

這是一個如何考慮解決這些問題,通過對您的問題進行快速重構一個小例子:

function pluck (key) { 
 
    return function pluckFrom(obj) { return obj[key]; }; 
 
} 
 

 
angular.module("app", ["ui.bootstrap"]); 
 

 
angular.moule("app").service("omdbService", ["$http", function ($http) { 
 
    function getSearch (search) { 
 
    var searching = $http.get("http://www.omdbapi.com/?s=" + search + "&r=json") 
 
     .then(pluck("data")); 
 
    return searching; 
 
    } 
 

 
    function getMovie (title) { 
 
    var searching = $http.get("http://www.omdbapi.com/?t=" + title + "&y=&plot=full&r=json") 
 
     .then(pluck("data")); 
 
    return searching; 
 
    } 
 

 
    return { 
 
    getSearch: getSearch, 
 
    getMovie: getMovie, 
 
    getPlaceholderPoster: function() { return "http://placehold.it/350x450/FF6F59/FFFFFF&text=Image+not+Available!!"; } 
 
    }; 
 
}]); 
 

 

 

 
angular.moule("app").controller("ListCtrl", ["$scope", "$q", "omdbService", function ($scope, $q, omdb) { 
 
    function loadMovie (movie) { 
 
    return omdb.getMovie(movie.Title)["catch"](function() { return undefined; }); 
 
    } 
 
    function movieExists (movie) { return !!movie; } 
 
    function updatePoster (movie) { 
 
    movie.Poster = movie.Poster || omdb.getPlaceholderPoster(); 
 
    return movie; 
 
    } 
 
    function setResults (movies) { 
 
    $scope.movie = movies; // $scope.movies, instead? 
 
    $scope.results = true; 
 
    $scope.error = false; 
 
    $scope.loading = false; 
 
    } 
 

 
    function handleError() { 
 
    $scope.results = false; 
 
    $scope.error = true; 
 
    } 
 

 
    $scope.submit = function() { 
 
    $scope.loading = true; 
 
    $scope.error = false; 
 

 
    omdb.getSearch($scope.search) 
 
     .then(pluck("Search")) 
 
     .then(function (movies) { return $q.all(movies.map(loadMovie)); }) 
 
     .then(function (movies) { return movies.filter(movieExists).map(updatePoster); }) 
 
     .then(setResults, handleError); 
 
    }; 
 

 
}]);

有處理這個8000種的有效方式,每個人都會看到它有點不同。
這也不是真的如何在生產中解決它,但不是太遙遠......

將所有端點調用移出到負責這些的服務,這意味着系統中的任何控制器(與該模塊作爲依賴)可以訪問它們。

每個功能做小事情,讓陣列。原型方法進行迭代(如果需要,可以對IE8進行微調)意味着每個函數都是超級特定的。

通過將控制器/服務函數包裝在數組中,並命名它們的依賴關係,它們現在變得友好。

submit()正文少於10行,處理各種瘋狂的異步的東西,但我知道我已經處理了錯誤,如一個電影返回一個404(我的代碼仍然應該觸發,與剩下的電影,別人的代碼可能不會 - 大多數代碼要麼永遠不會觸發成功,要麼會一直通過程序失敗,如果服務器爲電影拋出錯誤)。 現在,我沒有檢查服務器是否爲「電影」發送正確的數據,但這是不同的。

+0

我嘗試了你的代碼。這只是在開始時初始化我的代碼中的所有內容,比如錯誤notif,加載notif等。如果你想我可以發佈repo鏈接爲你做出貢獻。 –

+0

在接下來的幾天裏,我一定會看看,然後可能會提交PR。 – Norguard