AngularJS: Wie wechsle ich Ansichten von einer Controller-Funktion?

237

Ich versuche, die ng-click- Funktion von AngularJS zu verwenden, um die Ansicht zu wechseln. Wie würde ich dies mit dem folgenden Code tun?

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

Antworten:

314

Um zwischen verschiedenen Ansichten zu wechseln, können Sie die Datei window.location (mithilfe des Dienstes $ location!) In der Datei index.html direkt ändern

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

und konfigurieren Sie den Router so, dass er je nach Standort zu verschiedenen Partials wechselt (siehe hier https://github.com/angular/angular-seed/blob/master/app/app.js) ). Dies hätte den Vorteil der Historie sowie der Verwendung von ng-view.

Alternativ verwenden Sie ng-include mit verschiedenen Partials und verwenden dann einen ng-Schalter, wie hier gezeigt ( https://github.com/ganarajpr/Angular-UI-Components/blob/master/index.html ).

Ganaraj
quelle
Ich erhalte eine Fehlermeldung, dass Hash nicht von $ location abhängt.
The_Brink
Ich sehe Hash nicht als Teil des $ location-Objekts, aber es gibt eine $$ Hash-Variable, so dass es funktioniert und wenn ja, funktioniert es nicht.
The_Brink
OK, ich habe herausgefunden, wie es geht. $ location.path (Ansicht); ( docs.angularjs.org/guide/dev_guide.services.$location )
The_Brink
@The_Brink Danke für die Bearbeitung. Ich weiß nicht, warum es abgelehnt wurde. Ich habe Änderungen vorgenommen, um zu reflektieren, was ich sagen wollte.
Ganaraj
2
Das Beste, was Sie tun können, ist, einen normalen Link zu erstellen. <a href="https://stackoverflow.com/edit">Edit</a> Angular stellt sicher, dass durch den Klick kein erneutes Laden der Seite erstellt wird. Dieses Verhalten kann so geändert werden, dass es bei Bedarf ein erneutes Laden auslöst.
Anthony Martin
38

Die bereitgestellte Antwort ist absolut korrekt, aber ich wollte sie für zukünftige Besucher erweitern, die dies möglicherweise etwas dynamischer tun möchten -

In der Ansicht -

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

In der Steuerung -

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

Gleiches Grundkonzept wie die akzeptierte Antwort, nur dynamischer Inhalt hinzufügen, um ein wenig zu verbessern. Wenn die akzeptierte Antwort dies hinzufügen möchte, werde ich meine Antwort löschen.

PW Kad
quelle
8
ein totaler Trottel, aber zu Ihrer Information, a urlist eigentlich die vollständige Webadresse, einschließlich des Protokolls (http: //) und allem. Wie von $location.path()Ihrer Variablen impliziert , wird besser als beschrieben path.
Zach Lysobey
Dafür ist jedoch ein $ rootScope erforderlich. $ Digest (); oder $ scope. $ apply (); um es unverzüglich in Bewegung zu setzen.
Raz
23

Ich habe ein Beispiel.

So sieht mein Dokument aus:

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

So sieht mein Teil aus:

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

So sieht meine Strg aus:

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

App ist mein Modul:

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

Hoffe das ist hilfreich!

Cody
quelle
12

Die Methode, die für alle vorherigen Antworten auf diese Frage verwendet wurde, schlägt vor, die URL zu ändern, was nicht erforderlich ist, und ich denke, die Leser sollten sich einer alternativen Lösung bewusst sein. Ich verwende UI-Router und $ stateProvider, um einer templateUrl einen Statuswert zuzuordnen, der auf die HTML-Datei für Ihre Ansicht verweist. Dann müssen Sie nur noch den $ state in Ihren Controller einfügen und $ state.go ('state-value') aufrufen, um Ihre Ansicht zu aktualisieren.

Was ist der Unterschied zwischen Angular-Route und Angular-UI-Router?

Gavin Palmer
quelle
5

Dafür gibt es zwei Möglichkeiten:

Wenn Sie einen UI-Router verwenden oder $stateProviderwie folgt:

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

Wenn Sie einen Winkelrouter verwenden oder Folgendes $routeProvidertun:

$location.path('routeName'); //similarily include $location service in your controller
Sukhminder Parmar
quelle
Was mich auslöste, war die Verwendung des Routennamens anstelle des Statusnamens ... dh es sollte "main" anstelle von "/ main" sein
Ben Schmidt
3

Ohne die Standard-Routing-Umgebung (# / ViewName) vollständig zu überarbeiten, konnte ich Codys Tipp leicht modifizieren und es funktionierte hervorragend.

Der Controller

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

die Aussicht

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

Als ich versuchte, ein Kendo Mobile UI-Widget in eine eckige Umgebung zu integrieren, verlor ich den Kontext meines Controllers und das Verhalten des regulären Ankertags wurde ebenfalls entführt. Ich habe meinen Kontext innerhalb des Kendo-Widgets wiederhergestellt und musste eine Navigationsmethode verwenden ... das hat funktioniert.

Danke für die vorherigen Beiträge!

beauXjames
quelle
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'); 

Hoffe das wird dir helfen

Vaishali Tekale
quelle
2

Diese kleine Funktion hat mir gute Dienste geleistet:

    //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;
        }


    };

Sie benötigen nicht den vollständigen Pfad, sondern nur die Ansicht, zu der Sie wechseln

Shawn Dotey
quelle