AngularJS: Come posso cambiare vista da una funzione del controller?


237

Sto cercando di utilizzare la funzione ng-click di AngularJS per cambiare visualizzazione. Come farei per fare questo con il codice qui sotto?

index.html

 <div ng-controller="Cntrl">
        <div ng-click="someFunction()">
            click me
        <div>
    <div>

controller.js

  function Cntrl ($scope) {
        $scope.someFunction = function(){
            //code to change view?
        }
    }

Risposte:


314

Per passare da una vista all'altra, è possibile modificare direttamente window.location (utilizzando il servizio $ location!) Nel file index.html

<div ng-controller="Cntrl">
        <div ng-click="changeView('edit')">
            edit
        </div>
        <div ng-click="changeView('preview')">
            preview
        </div>
</div>

Controller.js

function Cntrl ($scope,$location) {
        $scope.changeView = function(view){
            $location.path(view); // path not hash
        }
    }

e configura il router per passare a diversi parziali in base alla posizione (come mostrato qui https://github.com/angular/angular-seed/blob/master/app/app.js ). Ciò avrebbe il vantaggio della storia e l'uso di ng-view.

In alternativa, usi ng-include con diversi parziali e quindi usi un interruttore ng come mostrato qui ( https://github.com/ganarajpr/Angular-UI-Components/blob/master/index.html )


Ricevo un errore che dice che l'hash non è una funzione di $ location.
The_Brink,

Non vedo l'hash come parte dell'oggetto $ location, ma esiste una variabile hash $$ quindi è così e in tal caso non funziona.
The_Brink,

OK, ho scoperto come farlo. $ location.path (vista); ( docs.angularjs.org/guide/dev_guide.services.$location )
The_Brink

@The_Brink Grazie per la modifica. Non so perché sia ​​stato respinto. Ho apportato modifiche per riflettere ciò che stavo tentando di dire.
Ganaraj,

2
La cosa migliore da fare in realtà è semplicemente creare un collegamento normale. <a href="https://stackoverflow.com/edit">Edit</a> Angular si assicurerà che il clic non crei una ricarica della pagina. Questo comportamento può essere modificato in modo da innescare una ricarica se lo si desidera.
Anthony Martin,

38

La risposta fornita è assolutamente corretta, ma volevo espandermi per eventuali visitatori futuri che potrebbero voler farlo un po 'più dinamicamente -

Nella vista -

<div ng-repeat="person in persons">
    <div ng-click="changeView(person)">
        Go to edit
    <div>
<div>

Nel controller -

$scope.changeView = function(person){
    var earl = '/editperson/' + person.id;
    $location.path(earl);
}

Stesso concetto di base della risposta accettata, aggiungendo solo un po 'di contenuto dinamico per migliorare un po'. Se la risposta accettata desidera aggiungere questo, eliminerò la mia risposta.


8
un nitpick totale, ma FYI, a urlè in realtà l' indirizzo web completo , incluso il protocollo (http: //) e tutto il resto. Come implica la $location.path()tua variabile, è meglio descritta come a path.
Zach Lysobey,

Ma richiede un $ rootScope. $ Digest (); o $ scope. $ apply (); per farlo muovere senza indugio.
Raz,

23

Ho un esempio funzionante.

Ecco come appare il mio documento:

<html>
<head>
    <link rel="stylesheet" href="css/main.css">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular-resource.min.js"></script>
    <script src="js/app.js"></script>
    <script src="controllers/ctrls.js"></script>
</head>
<body ng-app="app">
    <div id="contnr">
        <ng-view></ng-view>
    </div>
</body>
</html>

Ecco come appare il mio parziale:

<div id="welcome" ng-controller="Index">
    <b>Welcome! Please Login!</b>
    <form ng-submit="auth()">
        <input class="input login username" type="text" placeholder="username" /><br>
        <input class="input login password" type="password" placeholder="password" /><br>
        <input class="input login submit" type="submit" placeholder="login!" />
    </form>
</div>

Ecco come appare il mio Ctrl:

app.controller('Index', function($scope, $routeParams, $location){
    $scope.auth = function(){
        $location.url('/map');
    };
});

l'app è il mio modulo:

var app = angular.module('app', ['ngResource']).config(function($routeProvider)...

Spero sia utile!


12

Il metodo utilizzato per tutte le risposte precedenti a questa domanda suggerisce di cambiare l'URL che non è necessario e penso che i lettori dovrebbero essere consapevoli di una soluzione alternativa. Uso ui-router e $ stateProvider per associare un valore di stato a templateUrl che punta al file html per la tua vista. Quindi si tratta solo di iniettare $ state nel controller e chiamare $ state.go ('state-value') per aggiornare la vista.

Qual è la differenza tra angular-route e angular-ui-router?


5

Ci sono due modi per questo:

Se stai usando ui-router o $stateProvider, fallo come:

$state.go('stateName'); //remember to add $state service in the controller

se si utilizza il router angolare o $routeProvider, farlo come:

$location.path('routeName'); //similarily include $location service in your controller

La cosa che mi ha fatto inciampare è stato usare il nome della rotta invece del nome dello stato ... cioè dovrebbe essere "principale" anziché "/ principale"
Ben Schmidt,

3

Senza fare un rinnovamento completo dell'ambiente di routing predefinito (# / ViewName), sono stato in grado di fare una leggera modifica del suggerimento di Cody e farlo funzionare alla grande.

il controller

.controller('GeneralCtrl', ['$route', '$routeParams', '$location',
        function($route, $routeParams, $location) {
            ...
            this.goToView = function(viewName){
                $location.url('/' + viewName);
            }
        }]
    );

la vista

...
<li ng-click="general.goToView('Home')">HOME</li>
...

Ciò che mi ha portato a questa soluzione è stato quando stavo tentando di integrare un widget dell'interfaccia utente di Kendo Mobile in un ambiente angolare, stavo perdendo il contesto del mio controller e anche il comportamento del normale tag di ancoraggio veniva dirottato. Ho ristabilito il mio contesto all'interno del widget di Kendo e avevo bisogno di usare un metodo per navigare ... ha funzionato.

Grazie per i post precedenti!


2
Firstly you have to create state in app.js as below

.state('login', {
      url: '/',
      templateUrl: 'views/login.html',
      controller: 'LoginCtrl'
    })

and use below code in controller

 $location.path('login'); 

Spero che questo ti possa aiutare


2

Questa piccola funzione mi ha servito bene:

    //goto view:
    //useage -  $scope.gotoView("your/path/here", boolean_open_in_new_window)
    $scope.gotoView = function (st_view, is_newWindow)
    {

        console.log('going to view: ' + '#/' + st_view, $window.location);
        if (is_newWindow)
        {
            $window.open($window.location.origin + $window.location.pathname + '' + '#/' + st_view, '_blank');
        }
        else
        {
            $window.location.hash = '#/' + st_view;
        }


    };

Non è necessario il percorso completo, ma solo la vista a cui si sta passando

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.