2013-12-16 53 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

我希望在头几个小时之前看到这个答案,如何做到这一点。非常感谢你的努力 –

相关问题