Làm thế nào / khi nào sử dụng ng-click để gọi một tuyến đường?


243

Giả sử bạn đang sử dụng các tuyến đường:

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

Và trong html của bạn, bạn muốn điều hướng đến trang about khi nhấp vào nút. Một cách sẽ là

<a href="#/about">

... nhưng có vẻ như ng-click cũng hữu ích ở đây.

  1. Giả định đó có đúng không? Đó là ng-click được sử dụng thay vì neo?
  2. Nếu vậy, làm thế nào sẽ làm việc? I E:

<div ng-click="/about">



ui-sref Xem câu trả lời này: stackoverflow.com/a/21105057/2539811
Giám mục Vincil

Câu trả lời:


430

Các tuyến theo dõi $locationdịch vụ và phản hồi các thay đổi trong URL (thường thông qua hàm băm). Để "kích hoạt" một tuyến đường, bạn chỉ cần thay đổi URL. Cách dễ nhất để làm điều đó là với các thẻ neo.

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

Không có gì phức tạp hơn là cần thiết. Tuy nhiên, nếu bạn phải làm điều này từ mã, cách thích hợp là sử dụng $locationdịch vụ:

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

Mà, ví dụ, một nút có thể kích hoạt:

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

6
Cái này không hoạt động với tôi, nhưng bằng cách thay thế $ location.hash (hàm băm); với $ location.path (hàm băm); nó hoạt động. Điều này được đề xuất bởi @sean trong một câu trả lời khác, trong đó có ít phiếu hơn vì một số lý do.
Mỗi nhiệm vụ Aronsson

2
@PerQuestedAronsson pathhashphục vụ hai mục đích khác nhau nhưng tùy theo hoàn cảnh có thể có tác dụng tương tự. Đối với hầu hết các trường hợp, đối với định tuyến nghiêm ngặt (đặc biệt là html5modeđã bật), pathsẽ là lựa chọn chính tắc. Tôi đã cập nhật câu trả lời để phản ánh điều này.
Josh David Miller

2
@DavidWoods Nó sẽ hoạt động, nhưng chỉ khi đường dẫn cơ sở khớp /. Nếu bạn đang phục vụ ứng dụng từ /app/index.htmlđó, thì điều này sẽ không hoạt động vì URL tuyệt đối là /app/next.html. Rõ ràng là cũng vậy, máy chủ phải được đặt để trả về index.htmltệp của bạn khi nhấn vào /next.html. Vui lòng gửi Plunker / Fiddle nếu bạn muốn tôi xem qua.
Josh David Miller

2
Đây là một điều rất chung chung và hữu ích để làm. Có cách nào để tập trung hóa nó, hay chúng ta thực sự phải thêm một gophương thức cho mọi bộ điều khiển? (Hoặc tạo bộ điều khiển gốc bằng một gophương thức?)
Bennett McElwee

3
@BennettMcElwee Tôi nghĩ rằng cách tiếp cận tốt nhất là chỉ sử dụng thẻ neo; thẻ nút không cung cấp giá trị trong trường hợp này và đó là điều đang tạo ra vấn đề. Điều đó nói rằng, bạn có thể dễ dàng tạo một lệnh để làm điều này cho bạn, ví dụ : <button click-go="/home">Click</button>. Chức năng liên kết sẽ chỉ là thế này:element.on("click", function () { $location.path(attrs.clickGo); });
Josh David Miller

83

Đây là một mẹo tuyệt vời mà không ai đề cập đến. Trong bộ điều khiển có chức năng nằm trong, bạn cần bao gồm nhà cung cấp vị trí:

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
tuyệt thật, cảm ơn nhé! câu trả lời này hoạt động tốt hơn đối với tôi, bởi vì phương thức băm nối các giá trị trên url (được mã hóa) và phương thức đường dẫn cho phép tôi thay thế url đầy đủ, đó là những gì tôi cần. cảm ơn!
jfplataroti

8
Đây là giải pháp được đề xuất duy nhất trên trang này thực sự hoạt động. Không biết tại sao câu trả lời khác có nhiều phiếu hơn câu này ..?
Mỗi nhiệm vụ Aronsson

Tôi đã thử điều này, nhưng nó không hoạt động. Tôi có phải thêm vị trí cho mô-đun trước khi gắn nó vào bộ điều khiển không?
Fallenreaper

Điều này hiệu quả với tôi khi tôi đặt ng-click vào div chứ không phải <a>.
Steve

33

Sử dụng một thuộc tính tùy chỉnh (được thực hiện bằng một lệnh) có lẽ là cách sạch nhất. Đây là phiên bản của tôi, dựa trên đề xuất của @Josh và @ 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);
                });
            });
        }
    }
}]);

Nó có một số tính năng hữu ích, nhưng tôi chưa quen với Angular nên có lẽ cần phải cải thiện.


Điều này có tạo ra sự kiện nhấp chuột vào phần tử mỗi khi thuộc tính clickLink thay đổi không?
toxaq

@toxaq Nó chắc chắn không hoàn hảo. Tôi nghi ngờ rằng khi clickLinkthuộc tính thay đổi, lệnh sẽ thêm trình xử lý nhấp chuột mới nhưng giữ nguyên vị trí cũ. Kết quả có thể là một chút hỗn loạn. Ban đầu tôi đã viết cái này để sử dụng trong tình huống mà clickLinkthuộc tính sẽ không bao giờ thay đổi, vì vậy tôi không bao giờ bị trói cái kết lỏng lẻo này. Tôi nghĩ rằng việc sửa lỗi này thực sự sẽ dẫn đến mã đơn giản hơn - tôi có thể thử làm điều đó khi có thời gian (ha!)
Bennett McElwee

Mát mẻ. Vâng, nếu bạn lấy ra attrs. $ Quan sát nó sẽ hoạt động như dự định. Tôi sẽ dán phiên bản của mình ở đây nhưng nó sẽ không định dạng trong các bình luận và thực tế là giống hệt phần quan sát.
toxaq

@toxaq Tôi đã chỉnh sửa mã bây giờ. Tôi nghĩ rằng tôi đã điều chỉnh mã từ một số chỉ thị khác, đó là lý do tại sao không phù hợp attrs.$observe. Cảm ơn lời đề nghị của bạn.
Bennett McElwee

Đã đề nghị điều này khi đọc qua các câu trả lời được đề xuất. Làm sạch và tái sử dụng. +1
túc xá

4

Hãy nhớ rằng nếu bạn sử dụng ng-click để định tuyến, bạn sẽ không thể nhấp chuột phải vào phần tử và chọn 'mở trong tab mới' hoặc ctrl nhấp vào liên kết. Tôi cố gắng sử dụng ng-href khi đến điều hướng. ng-click tốt hơn để sử dụng trên các nút cho các hoạt động hoặc hiệu ứng hình ảnh như thu gọn. Nhưng về tôi sẽ không đề nghị. Nếu bạn thay đổi tuyến đường, bạn có thể cần thay đổi rất nhiều vị trí trong ứng dụng. Có một phương thức trả lại liên kết. ví dụ: Giới thiệu. Phương pháp này bạn đặt trong một tiện ích


1

Tôi đã sử dụng ng-clickchỉ thị để gọi một hàm, trong khi yêu cầu templateUrl tuyến đường, để quyết định cái nào <div>phải showhoặc hidebên trong trang templateUrl của tuyến đường hoặc cho các tình huống khác nhau.

AngularJS 1.6.9

Hãy xem một ví dụ, khi ở trang định tuyến, tôi cần thêm <div>hoặc chỉnh sửa <div>, mà tôi điều khiển bằng các mô hình bộ điều khiển chính $scope.addProduct$scope.editProductboolean.

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>

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

cả hai trang - RoutingTesting.html(cha mẹ), TestingPage.html(trang định tuyến) nằm trong cùng một thư mục,

Hy vọng điều này sẽ giúp được ai đó.


1

Một giải pháp khác nhưng không sử dụng ng-click vẫn hoạt động ngay cả đối với các thẻ khác ngoài <a>:

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

Bằng cách này, bạn cũng có thể truyền tham số cho tuyến đường của mình: https://stackoverflow.com/a/40045556/838494

(Đây là ngày đầu tiên của tôi với góc cạnh. Phản hồi nhẹ nhàng được chào đón)


0

Bạn có thể dùng:

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

Nếu bạn muốn một số biến động bên trong href, bạn có thể làm theo cách này:

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

Trong đó liên kết là biến phạm vi góc.


5
Điều này không trả lời câu hỏi OP, mà là về việc sử dụng ng-clickđể thay đổi vị trí.
jjmontes

0

chỉ cần làm như sau trong phần viết html của bạn:

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

Và trong bộ điều khiển của bạn, thêm $ state như sau:

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

$scope.going = function(){

$state.go('your route');

}

})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.