Come / quando usare ng-click per chiamare una rotta?


243

Supponiamo che tu stia utilizzando i percorsi:

// bootstrap
myApp.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {

    $routeProvider.when('/home', {
        templateUrl: 'partials/home.html',
        controller: 'HomeCtrl'
    });
    $routeProvider.when('/about', {
        templateUrl: 'partials/about.html',
        controller: 'AboutCtrl'
    });
...

E nel tuo html, vuoi navigare alla pagina about quando si fa clic su un pulsante. Un modo sarebbe

<a href="#/about">

... ma sembra che ng-click sia utile anche qui.

  1. Questa ipotesi è corretta? Che ng-click deve essere usato al posto dell'ancoraggio?
  2. In tal caso, come funzionerebbe? IE:

<div ng-click="/about">



ui-sref Vai a questa risposta: stackoverflow.com/a/21105057/2539811
Vincil Vescovo

Risposte:


430

Le route monitorano il $locationservizio e rispondono alle modifiche all'URL (in genere tramite l'hash). Per "attivare" un percorso, è sufficiente modificare l'URL. Il modo più semplice per farlo è con i tag anchor.

<a href="#/home">Go Home</a>
<a href="#/about">Go to About</a>

Non è necessario nulla di più complicato. Se, tuttavia, è necessario eseguire questa operazione dal codice, il modo corretto è utilizzare il $locationservizio:

$scope.go = function ( path ) {
  $location.path( path );
};

Che, ad esempio, un pulsante potrebbe attivare:

<button ng-click="go('/home')"></button>

6
Questo non ha funzionato per me, ma sostituendo $ location.hash (hash); con $ location.path (hash); Funziona. Questo è suggerito da @sean in un'altra risposta, che ha molti meno voti per qualche motivo.
Per Quested Aronsson, il

2
@PerQuestedAronsson pathe hashservono due scopi diversi, ma a seconda delle circostanze possono avere lo stesso effetto. Nella maggior parte dei casi, per l'instradamento rigoroso (specialmente con html5modeabilitato), pathsarà la scelta canonica. Ho aggiornato la risposta per riflettere questo.
Josh David Miller,

2
@DavidWoods Dovrebbe funzionare, ma solo se il percorso di base corrisponde /. Se stai fornendo l'app da /app/index.html, allora questo non funzionerà perché l'URL assoluto è /app/next.html. Ovviamente anche, il server deve essere impostato per restituire il index.htmlfile quando colpito a /next.html. Sentiti libero di pubblicare un Plunker / Fiddle se vuoi che io dia un'occhiata.
Josh David Miller,

2
Questa è una cosa molto generica e utile da fare. C'è un modo per centralizzarlo o dobbiamo davvero aggiungere un gometodo a ogni controller? (O creare un controller di root con un gometodo?)
Bennett McElwee,

3
@BennettMcElwee Penso che di gran lunga l'approccio migliore sia usare solo i tag anchor; il tag pulsante non fornisce alcun valore in questo caso ed è ciò che sta creando il problema. Detto questo, si potrebbe facilmente creare una direttiva per fare questo per voi, per esempio: <button click-go="/home">Click</button>. La funzione di collegamento sarebbe solo questa:element.on("click", function () { $location.path(attrs.clickGo); });
Josh David Miller,

83

Ecco un ottimo consiglio che nessuno ha menzionato. Nel controller all'interno della funzione, è necessario includere il provider di posizione:

app.controller('SlideController', ['$scope', '$location',function($scope, $location){ 
$scope.goNext = function (hash) { 
$location.path(hash);
 }

;]);

 <!--the code to call it from within the partial:---> <div ng-click='goNext("/page2")'>next page</div>

2
Figo, grazie! questa risposta ha funzionato meglio per me, perché il metodo hash aggiunge i valori sull'URL (codificato) e il metodo path mi ha permesso di sostituire l'URL completo, era quello di cui avevo bisogno. Grazie!
jfplataroti,

8
Questa è l'unica soluzione suggerita in questa pagina che ha funzionato. Non so perché un'altra risposta abbia molti più voti di questa ..?
Per Quested Aronsson, il

Ci stavo provando, ma non funziona. Devo aggiungere anche la posizione al modulo prima di collegarlo al controller?
Fallenreaper

Questo ha funzionato per me una volta impostato ng-click su un div piuttosto che su <a>.
Steve,

33

L'uso di un attributo personalizzato (implementato con una direttiva) è forse il modo più pulito. Ecco la mia versione, basata sui suggerimenti di @Josh e @ sean.

angular.module('mymodule', [])

// Click to navigate
// similar to <a href="#/partial"> but hash is not required, 
// e.g. <div click-link="/partial">
.directive('clickLink', ['$location', function($location) {
    return {
        link: function(scope, element, attrs) {
            element.on('click', function() {
                scope.$apply(function() {
                    $location.path(attrs.clickLink);
                });
            });
        }
    }
}]);

Ha alcune funzioni utili, ma sono nuovo di Angular, quindi probabilmente c'è spazio per miglioramenti.


Questo non crea un evento click sull'elemento ogni volta che cambia l'attributo clickLink?
toxaq,

@toxaq Non è assolutamente perfetto. Ho il sospetto che quando l' clickLinkattributo cambia, la direttiva aggiungerà il nuovo gestore di clic ma lascerà il vecchio in posizione. Il risultato potrebbe essere un po 'caotico. Inizialmente ho scritto questo da usare in una situazione in cui l' clickLinkattributo non cambierebbe mai, quindi non ho mai legato questa parte libera. Penso che correggere questo bug porterebbe effettivamente a un codice più semplice - Potrei provare a farlo quando ho tempo (ah!)
Bennett McElwee,

Freddo. Sì, se togli gli attr. $ Osserva funzionerà come previsto. Incollerei la mia versione qui, ma non verrà formattata nei commenti ed è praticamente identica a parte la parte osservata.
toxaq,

@toxaq Ho modificato il codice ora. Penso di aver adattato il codice da qualche altra direttiva, ecco perché attrs.$observec'era l'inadeguato . Grazie per i vostri suggerimenti.
Bennett McElwee,

Stava per suggerire questo quando leggevo le risposte suggerite. Pulito e riutilizzabile. +1
Dormouse,

4

Ricorda che se usi ng-click per il routing non sarai in grado di fare clic con il tasto destro del mouse sull'elemento e scegliere "apri in una nuova scheda" o ctrl facendo clic sul collegamento. Cerco di usare ng-href quando si tratta di navigazione. ng-click è meglio usare sui pulsanti per operazioni o effetti visivi come il collasso. Ma a proposito non lo consiglierei. Se si modifica il percorso, potrebbe essere necessario modificare molti posti nell'applicazione. Avere un metodo per restituire il collegamento. es: Informazioni. Questo metodo viene inserito in un'utilità


1

Ho usato la ng-clickdirettiva per chiamare una funzione, mentre richiedevo route templateUrl, per decidere quale <div>doveva essere showo hideall'interno della pagina route templateUrl o per diversi scenari.

AngularJS 1.6.9

Vediamo un esempio, quando nella pagina di routing, ho bisogno dell'aggiunta <div>o della modifica <div>, che controllo usando i modelli di controller padre $scope.addProducte $scope.editProductbooleani.

RoutingTesting.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Testing</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-route.min.js"></script>
    <script>
        var app = angular.module("MyApp", ["ngRoute"]);

        app.config(function($routeProvider){
            $routeProvider
                .when("/TestingPage", {
                    templateUrl: "TestingPage.html"
                });
        });

        app.controller("HomeController", function($scope, $location){

            $scope.init = function(){
                $scope.addProduct = false;
                $scope.editProduct = false;
            }

            $scope.productOperation = function(operationType, productId){
                $scope.addProduct = false;
                $scope.editProduct = false;

                if(operationType === "add"){
                    $scope.addProduct = true;
                    console.log("Add productOperation requested...");
                }else if(operationType === "edit"){
                    $scope.editProduct = true;
                    console.log("Edit productOperation requested : " + productId);
                }

                //*************** VERY IMPORTANT NOTE ***************
                //comment this $location.path("..."); line, when using <a> anchor tags,
                //only useful when <a> below given are commented, and using <input> controls
                $location.path("TestingPage");
            };

        });
    </script>
</head>
<body ng-app="MyApp" ng-controller="HomeController">

    <div ng-init="init()">

        <!-- Either use <a>anchor tag or input type=button -->

        <!--<a href="#!TestingPage" ng-click="productOperation('add', -1)">Add Product</a>-->
        <!--<br><br>-->
        <!--<a href="#!TestingPage" ng-click="productOperation('edit', 10)">Edit Product</a>-->

        <input type="button" ng-click="productOperation('add', -1)" value="Add Product"/>
        <br><br>
        <input type="button" ng-click="productOperation('edit', 10)" value="Edit Product"/>
        <pre>addProduct : {{addProduct}}</pre>
        <pre>editProduct : {{editProduct}}</pre>
        <ng-view></ng-view>

    </div>

</body>
</html>

TestingPage.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .productOperation{
            position:fixed;
            top: 50%;
            left: 50%;
            width:30em;
            height:18em;
            margin-left: -15em; /*set to a negative number 1/2 of your width*/
            margin-top: -9em; /*set to a negative number 1/2 of your height*/
            border: 1px solid #ccc;
            background: yellow;
        }
    </style>
</head>
<body>

<div class="productOperation" >

    <div ng-show="addProduct">
        <h2 >Add Product enabled</h2>
    </div>

    <div ng-show="editProduct">
        <h2>Edit Product enabled</h2>
    </div>

</div>

</body>
</html>

entrambe le pagine: RoutingTesting.html(padre), TestingPage.html(pagina di routing) si trovano nella stessa directory,

Spero che questo possa aiutare qualcuno.


1

Un'altra soluzione ma senza usare ng-click che funziona ancora anche con tag diversi da <a>:

<tr [routerLink]="['/about']">

In questo modo puoi anche passare parametri al tuo percorso: https://stackoverflow.com/a/40045556/838494

(Questo è il mio primo giorno con angolare. Il feedback delicato è il benvenuto)


0

Puoi usare:

<a ng-href="#/about">About</a>

Se vuoi qualche variabile dinamica all'interno di href puoi fare così:

<a ng-href="{{link + 123}}">Link to 123</a>

Dove link è la variabile dell'ambito angolare.


5
Questo non risponde alla domanda OP, che riguarda l'utilizzo ng-clickper cambiare posizione.
Jjmontes,

0

basta farlo come segue nella tua scrittura HTML:

<button ng-click="going()">goto</button>

E nel tuo controller, aggiungi $ state come segue:

.controller('homeCTRL', function($scope, **$state**) {

$scope.going = function(){

$state.go('your route');

}

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