2012-06-12 7 views
226

Sto tentando di utilizzare la funzione ng-click di AngularJS per cambiare visualizzazione. Come faccio a fare questo con il codice qui sotto?AngularJS: come si cambiano le viste da una funzione del controller?

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? 
     } 
    } 

risposta

303

Per passare da una vista, è possibile modificare direttamente il window.location (utilizzando il servizio di $ location!) In index.html file

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

Controller.js

e configurare 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 cronologia e l'utilizzo di ng-view.

In alternativa, è possibile utilizzare ng-includere con diversi parziali e quindi utilizzare un ng-switch come mostrato in qui (https://github.com/ganarajpr/Angular-UI-Components/blob/master/index.html)

+0

Ricevo un errore che dice che hash non è una funzione di $ posizione. –

+0

Non vedo l'hash come parte dell'oggetto $ posizione, ma c'è una variabile hash $$ così è e se così non funziona. –

+0

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

23

ho un esempio di lavoro.

Ecco come il mio doc appare:

<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 quello che i miei sguardi parziali come:

<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 ciò che il mio Ctrl assomiglia:

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

app è il mio modulo:

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

Spero che questo sia utile!

38

La risposta fornita è assolutamente corretto, ma ho voluto ampliare per tutti i futuri visitatori che potrebbero voler fare un po 'più dinamico -

Nella vista -

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

Nel controllore -

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

stesso concetto di base come la risposta accettata, solo l'aggiunta di un po 'di contenuti dinamici ad esso per migliorare un po'. Se la risposta accettata vuole aggiungerla, cancellerò la mia risposta.

+8

un nitpick totale, ma FYI, un 'url' è in realtà l'indirizzo web __full__, incluso il protocollo (http: //) e tutto il resto. Come implicito da '$ location.path()' la tua variabile è meglio descritta come 'percorso'. –

+5

@ZachL Risolto il problema –

+0

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

3

Senza fare un rinnovamento completo dell'ambiente di routing predefinito (#/ViewName), sono stato in grado di eseguire una leggera modifica del suggerimento di Cody e ho funzionato perfettamente.

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> 
... 

Quello che mi ha portato a questa soluzione è stato quando stavo cercando di integrare un widget di Kendo mobile UI in un ambiente angolare stavo perdendo il contesto anche il mio controller e il comportamento del normale tag di ancoraggio sono stati dirottati. Ho ristabilito il mio contesto all'interno del widget Kendo e avevo bisogno di usare un metodo per navigare ... questo ha funzionato.

Grazie per i post precedenti!

12

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

What is the difference between angular-route and angular-ui-router?

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 vi aiuterà a

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 avete bisogno il percorso completo, solo la vista si sta passando a

5

Ci sono due modi per questo:

Se si utilizza ui-router o $stateProvider, lo fanno come:

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

se si utilizza angolare-router o $routeProvider, lo fanno come:

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

La cosa che mi ha fatto inciampare era usare il nome del percorso al posto del nome dello stato ... cioè dovrebbe essere "principale" anziché "/ principale" –