角度应用,服务和工厂

时间:2015-01-06 15:23:58

标签: angularjs

我有以下Angular代码:

  var application = angular.module('Application', []);

  application.controller('ImageController', function ImageController($scope, $http) {

    $http.get('api/images').
      success(function (data, status, headers, config) {
        $scope.images = data;
      }).
      error(function (data, status, headers, config) { });

    $scope.vote = function (image) {

      $http.post('api/images/{key}/vote', { key: image.Key }).
        success(function (data, status, headers, config) {
        }).
        error(function (data, status, headers, config) {
        });

    };

  });
  1. 如何在共享同一个应用程序时将控制器放在不同的文件中? 我想我应该使用不同的方式定义控制器: application.controller('ImageController',...

  2. 我想我应该从控制器中删除$ http部分,对吗? 我正在阅读Angular Factories and Services,但我不确定该使用哪个。

    我对工厂的解释是根据要求提供服务的。 至少这是通常如何使用,例如,C#。

    但在我的示例中,我应该如何将$ http部分删除到服务/工厂?

    如何在Controller中注入它?

3 个答案:

答案 0 :(得分:2)

1)您只需在新文件中调用该模块,但不要重新定义它:

var application = angular.module('Application'); // no second parameter!

application.controller('newController', ...

或者,如果application是全局的,只需省略第一行。从技术上讲,每个文件可以有一个控制器,没问题。

注意:您必须省略module()方法中的第二个参数,请参阅Creation versus Retrieval此处:https://docs.angularjs.org/guide/module

2)是的,这些东西通常保存在服务/工厂中:

工厂

application.service('myService', function($http) {
    return {
        getStuff: function() { 
            return $http.get('api/images');
        },
        postStuff: function(image) { 
            return $http.post('api/images/{key}/vote', { key: image.Key });
        }
    }
});

控制器:

application.controller('ImageController', function ($scope, myService) {

   myService.getStuff()
      .success(function (data, status, headers, config) {
        $scope.images = data;
      })
      .error(function (data, status, headers, config) { });

   $scope.vote = function (image) {

     myService.postStuff(image)
        .success(function (data, status, headers, config) {
        })
        .error(function (data, status, headers, config) {
        });

    };

  });

请注意,我必须将服务作为依赖项注入控制器。


在这里查看完整工作版本(我添加了一个假的json文件,因为我们当然无法访问API)。它将代码显示在单独的文件中,以及如何与服务进行交互:http://plnkr.co/edit/rOG0XSxf2qE70Wyw1a8N?p=preview

答案 1 :(得分:0)

控制器函数接受函数的第二个参数,此函数ImageController可以在任何地方定义,包括另一个文件。

要记住一些事项,您需要使用您注入的服务数组来定义$ inject属性,以确保缩小安全性。

var application = angular.module('Application', []);
application.controller('ImageController', ImageController);

然后在其他地方:

function ImageController($scope, $http) {
  $http.get('api/images').
   success(function (data, status, headers, config) {
     $scope.images = data;
  }).
  error(function (data, status, headers, config) { });

  $scope.vote = function (image) {

    $http.post('api/images/{key}/vote', { key: image.Key }).
    success(function (data, status, headers, config) {
    }).
    error(function (data, status, headers, config) {
    });

  };
}
ImageController.$inject(['$scope','$http'])

或者,您可以在控制器文件中注册控制器,允许您只包含任何给定页面所需的控制器,但是我更喜欢将应用程序的控制器作为一个整体捆绑并缓存它。制作应用程序的地方存在于一个文件中,类似于其他语言生态系统中的DI配置

答案 2 :(得分:0)

1)如果要将代码拆分为单独的文件,则可能需要在每个文件中创建单独的模块。然后,您可以在创建模块时通过在方括号中列出它们的名称,将这些模块添加为主Application模块的依赖项。见下面的例子。

2)This answer很好地描述了工厂和服务之间的区别。基本上,你可以用两者做同样的事情;你只是用不同的方式写它们。您注入工厂/服务的方式与注入其他任何方式相同(例如$http$scope)。

如果您定义工厂,它可能如下所示:

<强> MyFactory.js

(function() {
  var application = angular.module('MyFactoryModule', []);

  application.factory('MyFactory', function ($http) {
    var myFactory = {
      images: null
    };

    $http.get('api/images').
      success(function (data, status, headers, config) {
        myFactory.images = data;
      }).
      error(function (data, status, headers, config) { });

    myFactory.vote = function (image) {
     $http.post('api/images/{key}/vote', { key: image.Key }).
       success(function (data, status, headers, config) {
       }).
       error(function (data, status, headers, config) {
       });
    };

    return myFactory;
  });
})();

<强>的application.js

(function() {
  // Notice how Application depends on MyFactoryModule
  var application = angular.module('Application', ['MyFactoryModule']);

  application.controller('ImageController', function ($scope, MyFactory) {

    // Example of how you might use MyFactory:
    MyFactory.vote(MyFactory.images[0]);

  });
})();