Same controller for different views

1

When defining routes, I have the following code:

$stateProvider
    .state('app', {
            url: '',
            abstract: true,
            views: {
                'login' : { templateUrl: 'view/login.html', controller: 'authentication' },
                'navbar-top' : { templateUrl: 'view/navbar-top.html', controller: 'authentication' },                    
                'recover' : { templateUrl: 'view/recover.html', controller: 'authentication' },
                'register' : { templateUrl: 'view/register.html', controller: 'authentication' }
            }
        })
...

I have different views with the same controller. In the 'navbar-top.html' view I have the 'login' and 'Register' buttons. When you click on "login" the view "login" should be changed, but nothing happens because the variables are not changed. From what I noticed, despite having the same controller, angular create a new instance for each view.

How to reuse and even controller for different views?

    
asked by anonymous 12.02.2015 / 14:24

2 answers

1

The correct way to share values between different scopes is to use a service (or, alternatively, a factory ). Following example:

var app = angular.module('app', []);
 
app.service('compartilhamentoService', function() {
    this.valor = 0;
});
 
app.controller('primeiroController', function($scope, compartilhamentoService) {
 $scope.svc = compartilhamentoService;
});

app.controller('segundoController', function($scope, compartilhamentoService) {
 $scope.svc = compartilhamentoService;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><divng-app="app">
    <div ng-controller="primeiroController">
        Primeiro controle:
        <input type="text" ng-model="svc.valor">
    </div>
    <div ng-controller="segundoController">
        Segundo controle:
        <input type="text" ng-model="svc.valor">
    </div>
</div>
    
14.04.2015 / 14:55
0

Not directly possible. But you can use service and prepare $scope to make it accessible and transparent.

The idea, in general terms, is as follows:

Each view of yours should be associated with a controller different or not. We assume it's the same, and let's call it DummyController . Its only function is to prepare the environment so that the controller (actually service ) is accessible and shared by the views.

Once this is done, implement your controller as a service in Javascript, with everything you have right, including DI.

Now, just DummyController prepare the environment to access the methods of the class.

Let's add code:

RealOne

angular.module("MyModule", []).factory("RealOne", [ "$http", function ($http) {
    var $scope = null;
    return {
        // método para atulizar o $scope quando a view é alterada.
        // deste modo, manipulamos sempre o $scope da view ativa.
        setScope: function ($newScope) {
            $scope = $newScope;
        },
        // implemente aqui o "controller real".
        fazAlgumaCoisa: function () {
            console.log("wooow");
            return "woooow";
        }
    }
}]);

DummyController

angular.module("MyModule", []).controller("DummyController", [ "$scope", "RealOne", function ($scope, RealOne) {
    $scope.ctrlr = RealOne; // faz com que o singleton seja acessível a view.
    RealOne.setScope($scope); // faz com que o scope correto seja acessível no singleton.
}]);

View

<p>{{ ctrlr.fazAlgumaCoisa() }}</p>

Now, just add the controller to the view, and it will be accessible by the ctrlr scope variable.

So, every time DummyController is instantiated, it will use the singleton we created in its first launch.

In this way, we use the life cycle management facilities of the Angular elements to our benefit, without any big hassle.

    
12.02.2015 / 16:44