在角应用中重用控制器,视图和服务

时间:2014-01-01 17:08:08

标签: angularjs

我希望我的应用从服务器API获取数据,假设我有以下API /orders/users。基本上我只想在表格中显示从服务器获得的json。我正在使用ng-table指令。所以,就我所拥有的组件而言:

  1. 服务 - 两个服务都做同样的事情 - 转到API并获取JSON
  2. 视图 - 两个API的相同视图,只显示不同的数据
  3. 控制器 - 从服务中获取数据并在表视图中显示它。
  4. 所以我看到它的方式,他们都做了同样的事情,只做了很小的调整。我想做的是

    angular.module('admin').config(function ($routeProvider, $locationProvider) {
      // same template and controller for both
      $routeProvider.
        when('/users', {
          templateUrl: '/partials/table.html',
          controllers: '/js/controllers/table.js
        }).
        when('/orders', {
          templateUrl: '/partials/table.html',
          controllers: '/js/controllers/table.js'
        });
    });
    

    在我的服务中

    factory('AdminService', ['$resource', function($resource) {
      // somehow I want to inject the right endpoint, depending on the route
      return $resource( '/:endpoint',
        { }, {} );
    }]);
    

    在我的桌面控制器中,我希望能够知道传递给服务的内容

    我当然可以为每个API端点使用单独的控制器和服务,它看起来像是浪费的代码重复,可以实现99%的相同功能

    这可能吗?

    如何将所有内容连接在一起?

1 个答案:

答案 0 :(得分:5)

如果您想要单独的路由,但需要相同的控制器,但有一些选项,您可以使用路由定义中的resolve选项来传递一些选项:

$routeProvider.
when('/users', {
  templateUrl: '/partials/table.html',
  controller: 'TableController',
  resolve: {
     'option1': function() {
        return 'val1'
     },
     'option2': function() {
        return 'val2'
     }
  }
}).
when('/orders', {
  templateUrl: '/partials/table.html',
  controller: 'TableController',
  resolve: {
     'option1': function() {
        return 'val3'
     },
     'option2': function() {
        return 'val4'
     }
  }
});  

然后两个案例中的控制器都将注入“option1”和“option2”,可用于自定义其行为:

app.controller('TableController', function($scope, option1, option2) {
  // Do something with option1 or option1
});

resolve对象函数中,您可以返回一个$resource对象,甚至可以返回一个在显示路径之前将使用某些数据解析的promise。您可以查看docs for $routeProvider了解详情。

编辑:对于资源,您可以编写一个可配置的工厂,如:

app.factory('MyResource', function($resource) {
  return function(endpoint) {
    return $resource('/' + endpoint);
  }
});

然后在控制器中使用它:

app.controller('TableController', function($scope, MyResource, endpoint) {
  var currentResource = MyResource(endpoint);
  currentResource.query(); // Whatever you want to do with the $resource;
}

假设“端点”是resolve中添加的选项之一,那么像

when('/orders', {
  templateUrl: '/partials/table.html',
  controller: 'TableController',
  resolve: {
     'endpoint': function() {
        return '/orders'
     }