Same controller for different views

Asked

Viewed 953 times

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 clicking "login" the "login" view should be changed, but nothing happens because the variables are not changed.
From what I understand, despite having the same controller, the angular create a new instance for each view.

How to reuse and same controller for different views?

2 answers

1

The correct way to share values between different scopes is by using a service (or, alternatively, a Factory). Example to follow:

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>

<div ng-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>

0

It is not possible directly. But you can use a service and prepare the $scope to make it accessible and transparent.

The general idea is as follows::

Each view of yours must be associated with a controller different or not. We assume it’s the same, and we’ll call it DummyController. Its only function will be to prepare the environment for the "controller" (actually the service) is accessible and shared by views.

Done this, implement your controller as a service in Javascript, with everything you’re entitled to, including DI.

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

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 scope variable ctrlr.

So, each time DummyController is instantiated, it will use the Singleton that we created in its first incialization.

In this way, we use the life cycle management facilities of Angular elements to our benefit, without great whims.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.