2013-12-16 74 views
13

我在Angular中非常綠色,我甚至不確定我是否正確地構建了搜索。整個指令和服務術語仍然讓我困惑,但那不是我的問題。AngularJS - 從服務中調用控制器功能

我讀過這個優秀的系列文章中從前到後:http://www.ng-newsletter.com/posts/beginner2expert-how_to_start.html

這就是爲什麼我在我的應用程序這一點。爲什麼我知道我的問題更多地涉及服務和控制器之間的關係。而不是語法相關。

因此,這裏的應用程序的概述:

我有一個控制器。這會消失,併爲使用AJAX調用PHP文件的用戶獲取一堆農場數據,並使用它自己的$ scope在屏幕上顯示它。

var masterApp = angular.module('masterApp', ['myFilters','commonControls']); 

masterApp.controller('MasterCtrl', ['$scope','$http', '$filter', 'commonFarmSelector', 
    function($scope, $http, $filter, commonFarmSelector){ 

     ... 

     $scope.masterCtrl.loadFarmData = function(farmId) { 
      var postdata = { 
       "farmId":farmId 
      }; 

      $http.post('/service/farmproduction', postdata).success(function (data) { 
       // Do stuff with the $scope using data 
      } 
     } 

     $scope.masterCtrl.loadFarms(); 
} 

你會看到我正在注入一種叫做「commonControls」的東西。這是我創建的一個模塊,用於保存將由多個控制器重用的控件。在這種情況下,包含農場的列表,用戶可以訪問(也由一個AJAX調用獲得)下拉場:

var commonControlsApp = angular.module('commonControls', []); 

commonControlsApp.controller('farmSelectorCtrl', ['$scope', '$http',function($scope, $http) { 

    $scope.farmSelectorCtrl ={} 

    // Change entire farm view when a different farm is selected 
    $scope.farmSelectorCtrl.switchUserFarm = function() { 
     var farmId = $scope.farmSelectorCtrl.selectedUserFarm; 
     $scope.masterCtrl.loadFarms(farmId); // !!! Direct link to masterCtrl 
    }; 

    // Get a list of the user's farms 
    $http.post('/service/userfarms').success(function (data) { 
     $scope.farmSelectorCtrl.userFarms = data.getFarmsPerUserResult.farmIds; 
    }); 

}]); 

這工作得很好。但正如你所看到的,farmSelector直接鏈接到masterCtrl。並且該loadFarmData函數的行爲特定於該控制器。換句話說,它只會做適用於該頁面的事情。

問題是,這個farmSelector將在其他頁面上使用。每個頁面的更改事件的確切行爲都會有所不同。所以我正在努力研究這種行爲應該放在哪裏。以及如何調用依賴於使用farmSelector的控制器。

我上面鏈接的文章表明這​​個farmSelector應該在一個服務中,以便它可以在其他地方重用。但是我仍然對如何在通用服務引發事件時採取特定行動感到困惑。

回答

11

我強烈推薦一項服務,同樣的原因,文章建議。它也對你的問題有一個很好的答案。

你想要什麼的技術術語是回調函數。恰恰是在事件觸發時採取的具體行動,文章的「服務」部分提供了一個很好的示例。

看看服務本文的這一部分(我已經下調的重要部件)

angular.module('myApp.services', []) 
    .factory('githubService', ['$http', function($http) { 

    var doRequest = function(username) { 
     return $http({ 
     url: 'https://MySuperURL.com/getTheData' 
     }); 
    } 

    return { 
     events: doRequest 
    }; 

}]); 

所以,我們已經有了一個服務現在,被稱爲githubService,其中有一個方法: events(這實際上只是doRequest一個不同的名字。我不停的重命名,以便它會與本文的代碼相匹配)

這裏隱藏在幕後是$q API,它有時也被稱爲'promise'API。函數$http返回一個'promise'對象,這實際上只是代碼跟蹤'promise'完成時會發生什麼的一種方式。例如,讓我們看看下面的代碼(再次從文章版本中修改):

app.controller('ServiceController', ['$scope', 'githubService', 
function($scope, githubService) { 

    // uses the $http service to call the GitHub API 
    // and returns the resulting promise 
    githubService.events(newUsername) 
    .success(function(data, status, headers) { 
     // do magic stuff with the result 
     // (which is in the data param) 
     $scope.events = data.data; 
    }) 
}); 

}]);

這就是發生'魔術'的地方。看看success()的調用,你會發現他們實際上傳遞了一個function,這個請求在請求運行時應該運行。該函數仍然可以訪問ServiceController中由於關閉而導致的所有變量,因此可以使用$scope和其他變量。但是,通過每次傳遞不同的函數,可以在每個控制器中編寫不同的success()方法,這使得多個控制器可以採取不同的操作。當請求完成時,它會調用每個給定的函數success

您可以按照此代碼示例獲取工作模型,但我也建議您查看$q in angular,並查看關於callback functions的文章。你需要理解兩者才能真正瞭解正在發生的事情,但好消息是它們都經常用在角度上,所以它會值得你花時間。

+0

我希望在頭幾個小時之前看到這個答案,如何做到這一點。非常感謝你的努力 –

相關問題