Angular - Using one controller for many coherent views across multiple HTTP requests

人盡茶涼 提交于 2019-12-17 19:28:29

问题


I have a simple Angular JS scenario. I show a list of experts in one view, and that list contains actions to edit an expert, which would be done in another view. These views are coming from server and are not in one file. They don't load together.

<!-- experts.html -->
<div ng-controller='expertController'>
    <!-- showing the list of experts here -->
</div>

And in another file on the server I have:

<!-- expert.html -->
<div ng-controller='expertController'>
    <!-- a form to edit/add an expert -->
</div>

And my controller is:

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;
                });
         });
    };
});

However, no data would be shown in the edit form. I inspected scopes using Batarang, but expert object won't be shown.

The problem seems to be that I use one controller for two (and optionally more than two) views. However, as I've read some other questions on SO, it seems that the best practice is to have one controller per HTML view.

However, I think it's more coherent and consistent to have one expertController to do all CRUD operations, alongside other actions related to expert. I think it's a little ugly to have expertEditController for edit form and expertListController for the list HTML.

What is the best practice here? How can I have a coherent and semantically named controller, and at the same time support many views. In any MVC framework that I've seen till now, it's something routine to support many views via one controller.


回答1:


Of course you can use many views with the same controller. For example: for editing and adding new items.

But you have to remember that each time the view is loaded the controller is initialized and fresh, new $scope is injected.

In your case it would be better to just use two separate controllers (one for experts and one for expert) and use -- optionally -- some service to communicate between those and maybe provide some caching mechanism.

UPDATE In case you want to provide some common/shared functionality between controllers the best way to go is to create and then inject a separate service. It keeps the code DRY.




回答2:


Here's an example project (not created by me) that illustrates how to use a single controller with two views: one for showing a list of items and one for editing or adding a single item: http://embed.plnkr.co/jAK31F/

The basic principle used in the controller is to check whether an id of a single item has been passed and run the applicable logic for that situation:

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
  }
});

The different views are configured in the routes like so:

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

So an url like baseurl/ will open the list view, and an url like baseurl/1 will open the detail view of the item with id 1.

With regard to this being a best practice or not, for most situations I don't think this method offers an advantage over using two controllers: one for the list, and one for a single item. In my experience a controller to view multiple items has different concerns than one for editing a single item. Any shared logic can be placed in a service as suggested in earlier answers.




回答3:


Actually when we use same controller for other view, it will reloads that controller whenever the view loads. At that moment scope will lose it's data.To avoid this i used $rootScope instead of $scope. I don't know whether this approach is correct or not but it works.

$rootScope.expert instead of $scope.expert.



来源:https://stackoverflow.com/questions/20312226/angular-using-one-controller-for-many-coherent-views-across-multiple-http-requ

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!