2015-12-25 43 views
2

我使用$ http.get構建我的第一個Angular應用程序,以便從github中提取原始json文件,並將每個json文件的輸出在頭文件在HTML中。我有的代碼正在工作,但非常多餘,我希望它可以重構。

我的控制器看起來是這樣的:

.controller('mycontroller', function($scope, $http) { 
    var firstUrl ='https://raw.githubusercontent.com/user/repo/master/first.json'; 
    var secondUrl ='https://raw.githubusercontent.com/user/repo/master/second.json'; 
    var thirdUrl ='https://raw.githubusercontent.com/user/repo/master/third.json'; 
    var fourthUrl ='https://raw.githubusercontent.com/user/repo/master/fourth.json'; 
    var fifthUrl ='https://raw.githubusercontent.com/user/repo/master/fifth.json'; 
    var sixthUrl ='https://raw.githubusercontent.com/user/repo/master/sixth.json'; 

    $http.get(firstUrl).success(function(data) { 
     $scope.firsts = data; 
    }); 

    $http.get(secondUrl).success(function(data) { 
     $scope.seconds = data; 
    }); 

    $http.get(thirdUrl).success(function(data) { 
     $scope.thirds = data; 
    }); 

    $http.get(fourthUrl).success(function(data) { 
    $scope.fourths = data; 
    }); 

    $http.get(fifthUrl).success(function(data) { 
    $scope.fifths = data; 
    }); 

    $http.get(sixthUrl).success(function(data) { 
    $scope.sixths = data; 
    }); 
}); 

我的HTML看起來像這樣:

<div ng-controller="mycontroller" id="content" class="container"> 
      <br/> 
      <div ng-repeat="first in firsts" class="panel panel-default"> 
       <h1 id="first">first</h1> 
       <div class="panel-heading"> 
        <h1><a href="{{first.url}}">{{first.company}}</a></h1> 
        <p>{{first.address}}</p> 
       </div> 
       <div class="list-group"> 
       <a ng-repeat="position in first.positions" class="list-group-item" href="{{first.url}}"> 
        {{position.title}} 
       </a> 
      </div> 
     </div> 
     </div> 
     <div ng-controller="mycontroller" id="content" class="container"> 
      <h1 id="second">second</h1> 
      <hr/> 
      <div ng-repeat="second in seconds" class="panel panel-default"> 
       <div class="panel-heading"> 
        <h1><a href="{{second.url}}">{{second.company}}</a></h1> 
        <p>{{second.address}}</p> 
       </div> 
      <div class="list-group"> 
       <a ng-repeat="position in second.positions" class="list-group-item" href="{{second.url}}"> 
        {{position.title}} 
       </a> 
      </div> 
     </div> 
     </div> 
     <div ng-controller="mycontroller" id="content" class="container"> 
      <h1 id="thirds">third</h1> 
      <hr/> 
      <div ng-repeat="third in thirds" class="panel panel-default"> 
       <div class="panel-heading"> 
        <h1><a href="{{third.url}}">{{third.company}}</a></h1> 
        <p>{{third.address}}</p> 
       </div> 
      <div class="list-group"> 
       <a ng-repeat="position in third.positions" class="list-group-item" href="{{third.url}}"> 
        {{position.title}} 
       </a> 
      </div> 
     </div> 
     </div> 
     <div ng-controller="mycontroller" id="content" class="container"> 
      <h1 id="fourth">fourth</h1> 
      <hr/> 
      <div ng-repeat="fourth in fourths" class="panel panel-default"> 
       <div class="panel-heading"> 
        <h1><a href="{{fourth.url}}">{{fourth.company}}</a></h1> 
        <p>{{fourth.address}}</p> 
       </div> 
      <div class="list-group"> 
       <a ng-repeat="position in fourth.positions" class="list-group-item" href="{{fourth.url}}"> 
        {{position.title}} 
       </a> 
      </div> 
     </div> 
    </div> 
     <div ng-controller="mycontroller" id="content" class="container"> 
      <h1 id="fifth">fifth</h1> 
      <hr/> 
      <div ng-repeat="fifth in fifths" class="panel panel-default"> 
       <div class="panel-heading"> 
        <h1><a href="{{fifth.url}}">{{fifth.company}}</a></h1> 
        <p>{{fifth.address}}</p> 
       </div> 
      <div class="list-group"> 
       <a ng-repeat="position in fifth.positions" class="list-group-item" href="{{fifth.url}}"> 
        {{position.title}} 
       </a> 
      </div> 
     </div> 
    </div> 
     <div ng-controller="mycontroller" id="content" class="container"> 
      <h1 id="sixth">sixth</h1> 
      <hr/> 
      <div ng-repeat="sixth in fifths" class="panel panel-default"> 
       <div class="panel-heading"> 
        <h1><a href="{{sixth.url}}">{{fifth.company}}</a></h1> 
        <p>{{sixth.address}}</p> 
       </div> 
      <div class="list-group"> 
       <a ng-repeat="position in sixth.positions" class="list-group-item" href="{{fifth.url}}"> 
        {{position.title}} 
       </a> 
      </div> 
     </div> 
    </div> 

回答

5

你可以使用數組:

.controller('mycontroller', function($scope, $http, $q) { 
    var urls = [ 
     'https://raw.githubusercontent.com/user/repo/master/first.json', 
     'https://raw.githubusercontent.com/user/repo/master/second.json', 
     'https://raw.githubusercontent.com/user/repo/master/third.json', 
     'https://raw.githubusercontent.com/user/repo/master/fourth.json', 
     'https://raw.githubusercontent.com/user/repo/master/fifth.json', 
     'https://raw.githubusercontent.com/user/repo/master/sixth.json' 
    ]; 

    var promises = urls.map(function(url) { 
     return $http.get(url); 
    }); 

    $q.all(promises).then(function(data) { 
     // data will represent an array containing the response from all 
     // AJAX requests 
     $scope.data = data; 
    }); 
}); 

,並在您的標記環比data陣列:

<div ng-controller="mycontroller" ng-repeat="elements in data" class="container"> 
    <h1>{{$index}}</h1> 
    <hr/> 
    <div ng-repeat="item in elements" class="panel panel-default"> 
     <div class="panel-heading"> 
      <h1><a href="{{item.url}}">{{item.company}}</a></h1> 
      <p>{{item.address}}</p> 
     </div> 
     <div class="list-group"> 
      <a ng-repeat="position in item.positions" class="list-group-item" href="{{item.url}}"> 
       {{position.title}} 
      </a> 
     </div> 
    </div> 
</div> 
+0

我們有幾乎相同的控制器代碼=),但我仍然認爲控制器應儘可能薄,打破標記可重複使用的餡餅ces(指令)和從這些片段組成index.html好得多。 – Denis

+0

我喜歡這種方法。唯一的問題是'$ q.all'是**不會失敗彈性**。如果任何'$ http.get'失敗,整個列表將無法顯示。隨着每個承諾的完成,填充'data'數組將很好,因此用戶可以看到部分結果。 – georgeawg

0

您可以將您的請求一個接一個地鏈接起來,以便在前一個請求完成後執行。

片段:

$http.get(url[0]) 
then(function(result){ 
    //get url[0] results 

    //make url[1] request 
    return $http.get(url[1]) 
}) 
.then(function(result){ 
    //get url[1] results 

    //make url[2] request 
    return $http.get(url[2]) 
}) 
.then(function(result){ 
    //get url[2] results 

    //make url[3] request 
    return $http.get(url[3]) 
}) 

等。現在你可以確定每個請求到服務器將在前一個請求完成後執行。

+0

但是爲什麼要等一個請求完成才能啓動下一個請求呢?並行執行它們將提供更好的用戶體驗,因爲結果將更快顯示。 –

+0

你需要確保一個請求在下一個開始之前完成一個主要原因,例如(並且在大型應用程序中發生這種情況,請相信我): 1.您可能需要數據才能從第一個請求返回以便使用他們在下一個請求等等。在這種情況下,您不希望在上一次完成之前開始下一個請求。 –

+0

我同意,如果您需要第一個請求中的數據以便創建第二個請求,那麼您應該讓它們連續。但在這種特殊情況下,這似乎並不是這種情況。 OP有6個不同的網址,可以單獨申請。 –

0

最好的方法是將邏輯分解爲獨立的部分並在指令中實現功能。因此,讓我們創建一個:

(function() { 
    'use strict'; 

    angular.module('test-app', []) 
     .controller('mainController', function ($scope) { 
      $scope.sourceUrls = [ 
       'https://raw.githubusercontent.com/user/repo/master/first.json', 
       'https://raw.githubusercontent.com/user/repo/master/second.json', 
       'https://raw.githubusercontent.com/user/repo/master/third.json', 
       'https://raw.githubusercontent.com/user/repo/master/fourth.json', 
       'https://raw.githubusercontent.com/user/repo/master/fifth.json', 
       'https://raw.githubusercontent.com/user/repo/master/sixth.json' 
      ]; 
     }) 
     .directive('sourceViewer', function ($http) { 
      return { 
       restrict: 'E', 
       templateUrl: 'your template url', //DO NOT FORGET TO PROVIDE PATH TO YOUR TEMPLATE HERE 
       scope: { 
        url: '=' 
       }, 
       link: function (scope, elem, attrs, ctrl) { 
        $http.get(scope.url).success(function (data) { 
         $scope.model = data.data; 
        }); 
       } 
      }; 
     }); 
    })(); 

而且你的指令模板應該是這樣的(含此標記到您的指令的templateUrl財產HTML文件提供路徑):

<h1>{{url}}</h1> 
<div> 
    <p>{{model.address}}</p> 
</div> 

然後使用該控制器您的index.html文件是這樣的:

<div ng-controller="main-controller"> 
    <source-viewer ng-repeat="sourceUrl in sourceUrls" url="sourceUrl"></div> 
</div>