Как / когда использовать ng-click для вызова маршрута?

Предположим, вы используете маршруты:

// 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'
    });
...

И в вашем html вы хотите перейти на страницу about при нажатии кнопки. Один из способов был бы

<a href="#/about">

... но, похоже, и здесь ng-click был бы полезен.

  1. Это предположение верно? Чтобы использовать ng-click вместо привязки?
  2. Если да, то как это будет работать? IE:

<div ng-click="/about">


person Robert Christian    schedule 07.01.2013    source источник
comment
возможный дубликат Как переключать представления в AngularJS из функции контроллера?   -  person Blazemonger    schedule 22.08.2014
comment
ui-sref См. этот ответ: stackoverflow.com/a/21105057/2539811   -  person Vincil Bishop    schedule 05.04.2016


Ответы (8)


Маршруты отслеживают службу $location и реагируют на изменения URL-адреса (обычно через хэш). Чтобы «активировать» маршрут, вы просто меняете URL. Самый простой способ сделать это - использовать якорные теги.

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

Ничего более сложного не нужно. Если, однако, вы должны сделать это из кода, правильный способ - использовать службу $location:

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

Что, например, может вызвать кнопка:

<button ng-click="go('/home')"></button>
person Josh David Miller    schedule 07.01.2013
comment
Это не сработало для меня, но заменив $ location.hash (hash); с помощью $ location.path (хеш); оно работает. Об этом говорит @sean в другом ответе, который по какой-то причине набрал гораздо меньше голосов. - person Per Quested Aronsson; 30.07.2013
comment
@PerQuestedAronsson path и hash служат двум разным целям, но в зависимости от обстоятельств могут иметь одинаковый эффект. В большинстве случаев для строгой маршрутизации (особенно с включенным html5mode) каноническим выбором будет path. Я обновил ответ, чтобы отразить это. - person Josh David Miller; 31.07.2013
comment
работает ли активация маршрута только с помощью тега привязки с html5mode? Когда у меня <a href="/next.html">Next</a> браузер перезагружает страницу, маршрутизатор не перехватывает ее. Должен ли я тогда делать это с помощью кода? - person David Woods; 16.08.2013
comment
@DavidWoods Это должно работать, но только если базовый путь совпадает с /. Если вы обслуживаете приложение из /app/index.html, это не сработает, потому что абсолютный URL-адрес - /app/next.html. Очевидно также, что сервер должен быть настроен так, чтобы возвращать ваш index.html файл при нажатии на /next.html. Не стесняйтесь размещать Plunker / Fiddle, если хотите, чтобы я посмотрел. - person Josh David Miller; 16.08.2013
comment
Это очень общий и полезный способ. Есть ли способ централизовать это, или нам действительно нужно добавить go метод к каждому контроллеру? (Или создать корневой контроллер с помощью метода go?) - person Bennett McElwee; 25.09.2013
comment
@BennettMcElwee Я думаю, что лучший подход - просто использовать теги привязки; тег кнопки не имеет значения в этом случае и является причиной проблемы. Тем не менее, вы можете легко создать директиву, которая сделает это за вас, например: <button click-go="/home">Click</button>. Функция ссылки будет только такой: element.on("click", function () { $location.path(attrs.clickGo); }); - person Josh David Miller; 25.09.2013
comment
Спасибо, Джош. В моем случае я хочу нажать на div для навигации, поэтому якорные теги бесполезны. Мне кажется, что директива - самый чистый подход. Но поскольку я уже использую директиву ngTap, мне нужно создать директиву ng-tap-go: \ - person Bennett McElwee; 25.09.2013
comment
Есть ли различия в производительности, доступности или стандартах, о которых мы должны знать при любом подходе? - person Will Strohl; 03.10.2015
comment
@WillStrohl Хороший вопрос. Я не знаю о каких-либо проблемах с производительностью или доступностью, если они обрабатываются должным образом. - person Josh David Miller; 04.10.2015
comment
Примечание: помните, что url чувствителен к регистру, и одна буква может вызвать у вас хорошую головную боль , как и у меня;) - person ; 28.03.2016
comment
Более того, префикс хеша должен соответствовать тому, что указано в конфигурации вашего провайдера маршрутов. Например, при следующем $locationProvider.hashPrefix('!'); необходимо обновить маршруты до #!/wherever. - person ThisClark; 12.07.2017

Вот отличный совет, о котором никто не упомянул. В контроллере, в котором находится функция, вам необходимо включить поставщика местоположения:

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>
person sean    schedule 27.06.2013
comment
хорошо, спасибо! этот ответ сработал для меня лучше, потому что метод хеширования добавляет значения в URL-адрес (закодированный), а метод пути позволяет мне заменить полный URL-адрес, это было то, что мне было нужно. Благодарность! - person jfplataroti; 15.07.2013
comment
Это единственное предложенное решение на этой странице, которое действительно сработало. Не знаю, почему у другого ответа намного больше голосов, чем у этого ..? - person Per Quested Aronsson; 30.07.2013
comment
Я пробовал это, но это не работает. Нужно ли мне добавить местоположение к модулю, прежде чем прикреплять его к контроллеру? - person Fallenreaper; 01.10.2016
comment
Это сработало для меня, когда я установил ng-click на div, а не на ‹a›. - person Steve; 03.12.2019

Использование настраиваемого атрибута (реализованного с помощью директивы), пожалуй, самый чистый способ. Вот моя версия, основанная на предложениях @Josh и @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);
                });
            });
        }
    }
}]);

В нем есть несколько полезных функций, но я новичок в Angular, поэтому, вероятно, есть возможности для улучшения.

person Bennett McElwee    schedule 25.09.2013
comment
Не будет ли это создавать событие щелчка для элемента каждый раз при изменении атрибута clickLink? - person toxaq; 20.11.2013
comment
@toxaq Это определенно не идеально. Я подозреваю, что при изменении атрибута clickLink директива добавит новый обработчик кликов, но оставит старый на месте. Результат может быть немного хаотичным. Изначально я написал это для использования в ситуации, когда clickLinkattribute никогда не изменится, поэтому я никогда не связывал этот свободный конец. Я думаю, что исправление этой ошибки на самом деле привело бы к упрощению кода - я мог бы попытаться сделать это, когда у меня будет время (ха!) - person Bennett McElwee; 20.11.2013
comment
Прохладный. Да, если вы удалите attrs. $ Наблюдайте, он будет работать, как задумано. Я бы вставил сюда свою версию, но она не будет форматироваться в комментариях и практически идентична части наблюдения. - person toxaq; 20.11.2013
comment
@toxaq Сейчас я отредактировал код. Думаю, я адаптировал код из какой-то другой директивы, поэтому там был несоответствующий attrs.$observe. Спасибо за ваши предложения. - person Bennett McElwee; 21.11.2013
comment
Собирался предложить это, читая предложенные ответы. Чистый и многоразовый. +1 - person Dormouse; 11.12.2014
comment
Это идеальное решение IMO, и оно НЕ добавляет новый обработчик кликов при изменении атрибута. Я пробовал это с Angular 1.6.3 - person Mustafa; 03.04.2017

Помните, что если вы используете ng-click для маршрутизации, вы не сможете щелкнуть элемент правой кнопкой мыши и выбрать «открыть в новой вкладке» или щелкнуть ссылку ctrl. Я стараюсь использовать ng-href, когда дело касается навигации. ng-click лучше использовать на кнопках для операций или визуальных эффектов, таких как сворачивание. Но про я бы не рекомендовал. Если вы измените маршрут, вам может потребоваться изменить многое, размещенное в приложении. Есть метод, возвращающий ссылку. Пример: О. Этот метод вы помещаете в утилиту

person Jens Alenius    schedule 16.11.2015

Я использовал директиву ng-click для вызова функции при запросе route templateUrl, чтобы решить, какой <div> должен быть show или hide внутри страницы route templateUrl или для разных сценариев.

AngularJS 1.6.9

Давайте посмотрим на пример, когда на странице маршрутизации мне нужно либо добавить <div>, либо изменить <div>, которые я контролирую с помощью моделей родительского контроллера $scope.addProduct и $scope.editProduct boolean.

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>

обе страницы - RoutingTesting.html (родительская), TestingPage.html (страница маршрутизации) находятся в одном каталоге,

Надеюсь, это кому-то поможет.

person ArifMustafa    schedule 08.04.2018

Другое решение, но без использования ng-click, которое по-прежнему работает даже для других тегов, кроме <a>:

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

Таким образом, вы также можете передать параметры своему маршруту: https://stackoverflow.com/a/40045556/838494

(Это мой первый день работы с angular. Мы приветствуем нежные отзывы)

person Albert Hendriks    schedule 12.04.2018
comment
это не следует отмечать как правильный ответ, поскольку он относится к angular 2+, а не к тому, что задает вопрос - angular 1 - person Nelson Bwogora; 08.11.2020

Вы можете использовать:

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

Если вам нужна какая-то динамическая переменная внутри href, вы можете сделать это следующим образом:

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

Где ссылка - это переменная области действия Angular.

person Sohail xIN3N    schedule 19.09.2015
comment
Это не отвечает на вопрос OP, который касается использования ng-click для изменения местоположения. - person jjmontes; 08.10.2015

просто сделайте это следующим образом в своем html-файле:

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

И в вашем контроллере добавьте $ state следующим образом:

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

$scope.going = function(){

$state.go('your route');

}

})
person LucasMugi    schedule 12.07.2018