Victor Sand
Victor Sand

Reputation: 2340

Reuse Angular view and controller with different parameters

I'm working with an Angular 1 frontend, talking to a very standard REST-ish API. The general structure consists of simple HTML views with corresponding controllers talking to some base URL which usually stays the same without each controller, for example /customer in this simplified example:

Controller

app.controller('customerCtrl', function($scope, $http) {
    $scope.loadCustomer = function() {
        $http.get('/customer/'+$scope.id) 
             .then(function(response) {
                 $scope.customer = response.customer;
             });
    };
    $scope.loadCustomerData = function() {
        $http.get('/customer/'+$scope.id+'/data') 
             .then(function(response) {
                 $scope.customerData = response.data;
             });
    };
});

View

<div ng-controller="customerCtrl">
    <input type="text" ng-model="id"></input>
    <button ng-click="loadCustomer()">Load Customer</button>
    <div>{{ customer.name }}</div>
    ...
    ...
</div>

And so on. The actual files are a few hundred lines long, each. Now all of a sudden, a new group of users are required to access the app. The frontend view and controller logic are the same, but they talk to a different backend base URL, for example /externalCustomer. The load function call would instead be to $http.get('/externalCustomer/'+$scope.id), and so on.

The views also need different URLs. If accessing the current view at http://app.com/#/customerView, the new one would be at http://app.com/#/externalCustomerView.

Given that there are many more view and controller methods like this (with a hardcoded backend URLs) and I'd rather not copy and paste a few hundred lines and have the logic diverge, what would be the proper way to implement this? It would be great to be able to reuse both the views and controllers and maybe pass some base URL parameter and/or view URL, but I'm not sure how to start.

Upvotes: 0

Views: 81

Answers (1)

Amit Malik
Amit Malik

Reputation: 194

In your routes

$routeProvider
        .when('/:baseUrl', {
            templateUrl: 'public/app/customerView.html',
            controller: 'customerViewCtrl',
            controllerAs: 'customerViewCtrl'                           
            }
        });

and in your controller inject $route and read the 'baseUrl' param as

$http.get('/'+$route.current.params.baseUrl+'/'+$scope.id+'/data') 
         .then(function(response) {
             $scope.customerData = response.data;
         });

in this way when you pass externalCustomer then that will be used for baseURL and same for customer

Another approach can be like this:

$routeProvider
        .when('/customerView', {
            templateUrl: 'public/app/customerView.html',
            controller: 'customerViewCtrl',
            controllerAs: 'customerViewCtrl',
            baseUrl: 'customer'               
            }
        }).when('/externalCustomerView', {
            templateUrl: 'public/app/customerView.html',
            controller: 'customerViewCtrl',
            controllerAs: 'customerViewCtrl',
            baseUrl: 'externalCustomer'                
        })

and in your controller inject $route and read the 'baseUrl' as

$http.get('/'+$route.current.baseUrl+'/'+$scope.id+'/data') 
         .then(function(response) {
             $scope.customerData = response.data;
         });

Upvotes: 5

Related Questions