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

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


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.


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!


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?


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

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!


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


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.