AngularJS - 从服务调用控制器函数 [英] AngularJS - Calling a controller function from a service

查看:27
本文介绍了AngularJS - 从服务调用控制器函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Angular 非常熟悉,我什至不确定我是否正确地构建了搜索.整个指令和服务术语仍然让我有些困惑,但这不是我的问题.

I'm so green at Angular, I'm not even sure I've been structuring a search for this correctly. The whole directive and service terminology is still confusing me some, but that isn't my question.

我已经从头到尾阅读了这个优秀的文章系列:http://www.ng-newsletter.com/posts/beginner2expert-how_to_start.html

I've read this excellent article series front to back: http://www.ng-newsletter.com/posts/beginner2expert-how_to_start.html

这就是为什么我现在在我的申请中.为什么我知道我的问题更多地与服务和控制器之间的关系有关.而不是与语法相关.

Which is why I am at this point in my application. And why I know my question relates more to the relationship between services and controllers. Rather than syntax-related.

以下是该应用的概述:

我有一个控制器.这会关闭并使用对 PHP 文件的 AJAX 调用为用户获取一堆农场数据,并使用它自己的 $scope 将其显示在屏幕上.

I have one controller. This goes off and gets a bunch of farm data for the user using an AJAX call to a PHP file, and displays it on screen using it's own $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 调用获得):

You will see I am injecting something called "commonControls". This was a module I created to hold controls that will be reused by multiple controllers. In this case, a dropdown field that contains a list of farms the user has access to (also obtained by an AJAX call):

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 函数的行为特定于该控制器.换句话说,它只会做适用于该页面的事情.

This works fine. But as you can see, the farmSelector is directly linked to masterCtrl. And the behavior of that loadFarmData function is specific to that controller. In other words, it will only do things that apply to that page.

问题是,这个 farmSelector 将用于其他页面.并且每个页面的更改事件的确切行为将不同.所以我正在努力弄清楚这种行为应该在哪里.以及如何根据使用 farmSelector 的控制器调用它.

The thing is, this farmSelector will be used on other pages. And the precise behavior of a change event will be different for each page. So I am struggling to work out where this behavior should sit. And how it would be called dependent on the controller using the farmSelector.

我上面链接的文章建议这个 farmSelector 应该在一个服务中,以便它可以在其他地方重用.但是我仍然对如何在触发事件时为通用服务提供特定操作感到困惑.

The article I have linked above suggests this farmSelector should be in a service so it can be reused elsewhere. But I am still confused over how you could give a generic service a specific action to take when an event is triggered.

推荐答案

我也强烈推荐一项服务,与文章建议的原因相同.它还可以很好地解决您的问题.

I highly recommend a service as well, for the same reason the article suggests. It also has a great answer to your problem.

您想要的技术术语是回调函数.准确地说,这是触发事件时要采取的特定操作,本文的服务部分提供了一个很好的示例,说明了如何执行此操作.

The technical term for what you want is a calback function. It is, precisely, a specific action to take when an event is triggered, and the Services section of the article provides a good example of how to do this.

查看服务文章的这一部分(我已将其精简为重要部分)

Take a look at this section of the Services article (which I've trimmed down to the important parts)

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 的不同名称code>; 我保留了重命名以便它与文章的代码匹配.)

So we've got a service now, called githubService, which has one method: events (which is really just a different name for doRequest; I kept the rename so that it would match with the article's code.)

隐藏在幕后的是 $q API,它有时被称为承诺"API.函数$http 返回一个'promise' 对象,这实际上只是代码跟踪'promise' 完成后会发生什么的一种方式.例如,让我们看看下一个代码(再次从文章的版本中修改):

Hidden here behind the scenes is the $q API, which is sometimes referred to as the 'promise' API. The function $http returns a 'promise' object, which is really just a way for the code to keep track of what should happen when the 'promise' is done. For example, let's look at this next code (again, modified from the article's version):

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 函数.

This is where the 'magic' is happening. Look at the call to success(), and you'll see that they are actually passing a function that should be run when the request works. The function still has access to all the variables in the ServiceController due to closure, so it's allowed to use $scope and other variables. However, it's very possible to write a different success() method in every controller by passing a different function each time, which lets multiple controllers take different actions. When the request finishes, it will call every success function that it was given.

您可以按照此代码示例获取工作模型,但我也建议您查看 $q in angular,也看看这篇关于 回调函数.您需要了解两者才能真正了解发生了什么,但好消息是它们都在 angular 中经常使用,因此值得您花时间.

You could follow this code example and get a working model, but I also suggest that you take a look at $q in angular, and also take a look at this article about callback functions. You need to understand both to really get what's going on, but the good news is that they are both used quite often in angular, so it will be worth your time.

这篇关于AngularJS - 从服务调用控制器函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆