Angular - 在多个HTTP请求中使用一个控制器来处理许多连贯的视图

Ham*_*ani 12 angularjs angularjs-scope

我有一个简单的Angular JS场景.我在一个视图中显示了一个专家列表,该列表包含编辑专家的操作,这将在另一个视图中完成.这些视图来自服务器,不在一个文件中.它们不会一起装载.

<!-- experts.html -->
<div ng-controller='expertController'>
    <!-- showing the list of experts here -->
</div>
Run Code Online (Sandbox Code Playgroud)

在服务器上的另一个文件中我有:

<!-- expert.html -->
<div ng-controller='expertController'>
    <!-- a form to edit/add an expert -->
</div>
Run Code Online (Sandbox Code Playgroud)

我的控制器是:

app.controller('expertController', function ($scope) {
    $scope.getExperts = function () {
        _.get('/expert/getexperts/', null, function (data) {
            $scope.$apply(function () {
                $scope.experts = data;
            });
        });
    };

    $scope.editExpert = function (index) {
        _.get('/expert/getexpert/', { id: $scope.experts[index].Id }, function (data) {
                $scope.$apply(function () {
                    $scope.expert = data;
                });
         });
    };
});
Run Code Online (Sandbox Code Playgroud)

但是,编辑表单中不会显示任何数据.我使用Batarang检查了范围,但是expert不会显示对象.

问题似乎是我为两个(可选两个以上)视图使用一个控制器.但是,正如我在SO上阅读的其他一些问题一样,最佳做法似乎是每个HTML视图都有一个控制器.

但是,我认为让一个expertController人完成所有CRUD操作以及与之相关的其他操作更加连贯和一致expert.我认为expertEditController编辑表单和expertListControllerHTML列表有点难看.

这里的最佳做法是什么?我怎样才能拥有一个连贯且语义命名的控制器,同时支持许多视图.在我迄今为止看到的任何MVC框架中,通过一个控制器支持许多视图是常规的.

art*_*iak 18

当然你可以使用views相同的许多controller.例如:用于编辑和添加新项目.

但是你必须记住,每次加载视图时,控制器都会被初始化并且是新的,$scope注入了new .

在你的情况下,最好只使用两个独立的控制器(一个用于experts和一个用于expert)和使用 - 可选 - 一些服务在这些之间进行通信,并可能提供一些缓存机制.

更新如果您想在控制器之间提供一些通用/共享功能,最好的方法是创建然后inject单独的服务.它保持代码DRY.

  • @artur你说"当然你可以使用相同的控制器使用很多视图.例如:用于编辑和添加新项目."你可以提供一个例子. (3认同)

Aro*_*ers 7

这是一个示例项目(不是由我创建的),它说明了如何使用具有两个视图的单个控制器:一个用于显示项目列表,另一个用于编辑或添加单个项目:http://embed.plnkr.co/jAK31F /

控制器中使用的基本原则是检查是否已传递单个项的id并为该情况运行适用的逻辑:

controllers.controller('MainController', function( $scope, $location, $routeParams, ItemService)  {
  if ($routeParams.itemid) {
    // do stuff for single item
    if ($routeParams.itemid == 0) {
      // do stuff for adding item
    } else {
      // do stuff for editing item
    }
  } else {
    // do stuff for listing multiple items
  }
});
Run Code Online (Sandbox Code Playgroud)

在路由中配置不同的视图,如下所示:

app.config(['$routeProvider', function ($routeProvider) {
        // routes
        $routeProvider.
        when('/', {
            templateUrl: 'item_list.html',
            controller: 'MainController'
        }).
        when('/:itemid', {
            templateUrl: 'item_single.html',
            controller: 'MainController'
        });
    }]);
Run Code Online (Sandbox Code Playgroud)

所以一个url baseurl/就会打开列表视图,一个url baseurl/1就会打开id为1的项目的详细视图.

关于这是一种最佳实践,在大多数情况下,我不认为这种方法比使用两个控制器更有优势:一个用于列表,一个用于单个项目.根据我的经验,用于查看多个项目的控制器与编辑单个项目的控制器具有不同的关注点.任何共享逻辑都可以按照前面的答案中的建议放在服务中.