2014-01-29 33 views
11

正如你將會看到我是AngularJS,JS和web開發中的新成員=)真的很抱歉,但我嘗試了。

我嘗試用AngularJS控制器構建一個巨大的webform(大約200個不同的領域)。我需要從控制器訪問根數據源。 AngularJS團隊要求服務不要僅僅用於存儲數據,但是我想爲加載和保存數據(在服務器上的.json文件中開始)提供服務。

服務:

AppName.factory('MasterData', ['$rootScope', '$http', '$q', '$log', 
    function($rootScope, $http, $q, $log) { 

    var responseData; 
    $http.get('/getdata.php').then(function (response) { 
     responseData = response.data; 
     console.log(response.data); 
    }); 

    return responseData; 

}]); 

控制器:

AppName.controller('justController', ['$scope', 'MasterData', '$log', 
    function ($scope, MasterData, $log) { 
     $scope.data = MasterData.justControllerSectionData; 
     console.log(MasterData); 
    } 
]); 

控制器返回undefined。但是來自服務的console.log返回對象。 我覺得這個問題太簡單了,但我找不到解決方法:( 另外我不能使用像控制器的.getData()這樣的函數來服務,因爲每次任何控制器都會詢問服務器的數據我有AngularJS應用程序中的路線與12-14控制器(完整的網絡形式除以部分),我認爲這是從後端得到數據一次是好的

PS我認爲有承諾的問題,但是當我嘗試使用這樣的代碼:

var defer = $q.defer(); 
$http.get('/getdata.php').success(function(data){ 
    defer.resolve(data); 
}); 
return defer; 

我有決心,有目標,拒絕等而實在無法理解我能做些什麼與它:(

幫我得到控制:)

+0

形成200場?你可能會好得多使用[流星和autoform](https://atmospherejs.com/aldeed/autoform): '{{> quickForm集合= 「書籍」 ID = 「insertBookForm」 TYPE = 「插入」}}' –

回答

18

您的代碼不工作的數據,因爲你在你的服務提供給success()回調異步調用;您的服務已返回之後,那就是:

的順序是這樣的:

  1. 在MasterData的function運行。 $http.get請求已啓動並附加了承諾回調。此回調中引用了responseData(又名「closed over」)。
  2. 該函數從服務返回到您的控制器。還沒有設置responseData,這並不會阻止父範圍函數返回。
  3. $http.get成功,並且responseData在服務中設置,但控制器無法訪問。

如果success()嵌套函數的範圍界定不明確你的,我建議你在閱讀的JavaScript閉包(甚至更好,在一般情況),例如here

你可以用這樣的服務實現自己的目標:

function($q, $http, /* ... */) {  
    return { 
     getData: function() { 
      var defer = $q.defer(); 
      $http.get('/getdata.php', { cache: 'true'}) 
      .then(function(response) { 
       defer.resolve(response); 
      }); 

      return defer.promise; 
    }; 
} 

$http服務會很樂意你的緩存響應數據,所以你不必。請注意,您需要檢索defer紅色物體的承諾才能完成此項工作。

控制器是這樣的:

/* omitted */ function($scope, YourService) { 
    YourService.getData().then(function(response) { 
     $scope.data = response.data; 
    }); 
} 

由於成功的折舊,我修改成功然後。

+0

我會閱讀更多關於JS可言,感謝您的鏈接。你的代碼返回的對象有than,catch和finally方法,我應該怎麼做才能獲得數據:)? – MrTwister

+0

傻了我,加入到答案:)。 –

1

服務應返回的承諾,而不是數據。這是異步的方式。

首先獲取的角度的run方法的價值。對於這個例子,我把它放在$ rootScope中,因爲這使得它可以被所有控制器中的所有範圍訪問。

AppName.run(['$http', '$rootScope', 
    function($http, $rootScope) { 
     console.log('Run'); 
     $http.get('http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo') 
     .success(function(data) { 
      $rootScope.resource = data; 
      console.log($rootScope.resource); 
     }); 
    } 
    ]) 

,除非你將其存儲在一些奇怪的地方這是不是真的有必要。

AppName.service('Resource',['$rootScope', 
    function($rootScope) { 
     return $rootScope.resource; 
    } 
    ]); 

爲什麼服務真的是沒有必要每個範圍將繼承在$ rootScope這就是值(

AppName.controller('mainController', ['$scope', 'Resource', 
    function($scope, Resource) { 
    console.log('controller'); 
    console.log(Resource); 
    } 
]); 

警告!!!這個值將無法使用,直到第一個控制器後負載。如果你在控制器中使用它,記住,你可以綁定爲HTML,但第一次通過控制器代碼,但尚未初始化的變量。

+1

如果我正確的解決方案將運行$ http.get每次當控制器將加載,所以如果我前進到另一個控制器,然後回到這一個 - 我會運行$ http.get。我需要獲取一次數據並將其存儲在服務中。 – MrTwister

+0

是的,是的。要僅運行一次,請在module.run()中調用它並將該值存儲在module.value()函數中; –

+0

是的,你只是忘記了,我有12個控制器,它們使用來自/getdata.php的數據,每個數據都在它自己的Angular的$ route上。如果我將數據存儲在一個控制器中,我不會在另一個控制器中獲取數據。所以我需要這項服務。可能是我在Angular應用程序的邏輯不好? – MrTwister

相關問題