ใช้ ng-click อย่างไรในการโทรหาเส้นทาง


243

สมมติว่าคุณกำลังใช้เส้นทาง:

// 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 ของคุณคุณต้องการนำทางไปยังหน้าเกี่ยวกับเมื่อมีการคลิกปุ่ม วิธีหนึ่งก็คือ

<a href="#/about">

... แต่ดูเหมือนว่า ng-click จะมีประโยชน์เช่นกัน

  1. สมมติฐานนั้นถูกต้องหรือไม่ ng-click นั้นจะถูกใช้แทนการยึด?
  2. ถ้าเป็นเช่นนั้นจะทำงานอย่างไร IE:

<div ng-click="/about">



ui-sref ดูคำตอบนี้: stackoverflow.com/a/21105057/2539811
Vincil Bishop

คำตอบ:


430

เส้นทางตรวจสอบ$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>

6
อันนี้ใช้ไม่ได้กับฉัน แต่ด้วยการเปลี่ยน $ location.hash (hash); ด้วย $ location.path (แฮช); มันได้ผล. @sean แนะนำโดยนี้ในการตอบกลับอื่นซึ่งมีคะแนนเสียงน้อยกว่ามากด้วยเหตุผลบางประการ
ต่อ quested Aronsson

2
@PerQuestedAronsson pathและhashให้บริการสองวัตถุประสงค์ที่แตกต่างกัน แต่ขึ้นอยู่กับสถานการณ์สามารถมีผลเช่นเดียวกัน สำหรับกรณีส่วนใหญ่สำหรับการกำหนดเส้นทางที่เข้มงวด (โดยเฉพาะเมื่อhtml5modeเปิดใช้งาน) pathจะเป็นตัวเลือกที่ยอมรับได้ ฉันปรับปรุงคำตอบเพื่อสะท้อนถึงสิ่งนี้
Josh David Miller

2
@DavidWoods มันควรจะทำงาน แต่ถ้าตรงกับเส้นทาง/หลัก หากคุณกำลังให้บริการแอปจาก/app/index.htmlนี้แล้วจะไม่ทำงานเพราะ URL /app/next.htmlที่แน่นอนคือ เห็นได้ชัดว่ายังเซิร์ฟเวอร์จะต้องตั้งค่ากลับของคุณไฟล์เมื่อตีindex.html /next.htmlรู้สึกฟรีเพื่อโพสต์ Plunker / ซอหากคุณต้องการให้ฉันดู
Josh David Miller

2
นี่เป็นสิ่งที่ทั่วไปมากและมีประโยชน์ที่ต้องทำ มีวิธีการรวมศูนย์หรือไม่หรือเราต้องเพิ่มgoวิธีการลงในคอนโทรลเลอร์ทุกตัวหรือไม่? (หรือสร้างรูทคอนโทรลเลอร์ด้วยgoเมธอด?)
Bennett McElwee

3
@BennettMcElwee ฉันคิดว่าวิธีที่ดีที่สุดคือใช้แท็กจุดยึด แท็กปุ่มไม่มีค่าในกรณีนี้และเป็นสิ่งที่สร้างปัญหา <button click-go="/home">Click</button>ที่กล่าวว่าคุณได้อย่างง่ายดายสามารถสร้างคำสั่งการทำเช่นนี้สำหรับคุณเช่น: ฟังก์ชั่นการเชื่อมโยงจะเป็นเช่นนี้:element.on("click", function () { $location.path(attrs.clickGo); });
Josh David Miller

83

นี่คือเคล็ดลับที่ยอดเยี่ยมที่ไม่มีใครพูดถึง ในตัวควบคุมที่ฟังก์ชันอยู่ภายในคุณต้องรวมผู้ให้บริการตำแหน่ง:

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
ขอบคุณมาก ๆ ! คำตอบนี้ทำงานได้ดีขึ้นสำหรับฉันเพราะวิธีแฮชผนวกค่าใน url (เข้ารหัส) และวิธีการเส้นทางให้ฉันแทนที่ URL เต็มนั่นคือสิ่งที่ฉันต้องการ ขอบคุณ!
jfplataroti

8
นี่เป็นทางออกเดียวที่แนะนำในหน้านี้ซึ่งใช้งานได้จริง ไม่ทราบว่าทำไมคำตอบอื่นมีคะแนนมากกว่านี้ ..
ต่อ Aronsson ที่ทำภารกิจ

ฉันพยายามทำสิ่งนี้ แต่มันไม่ทำงาน ฉันต้องเพิ่มตำแหน่งไปยังโมดูลด้วยหรือไม่ก่อนทำการติดตั้งเข้ากับคอนโทรลเลอร์
Fallenreaper

สิ่งนี้ใช้ได้กับฉันเมื่อฉันตั้งค่า ng-click ให้กับ div แทนที่จะเป็น <a>
Steve

33

การใช้แอตทริบิวต์ที่กำหนดเอง (ใช้กับคำสั่ง) อาจเป็นวิธีที่สะอาดที่สุด นี่คือเวอร์ชันของฉันตามคำแนะนำ @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 ดังนั้นอาจมีที่ว่างสำหรับการปรับปรุง


สิ่งนี้จะไม่สร้างกิจกรรมการคลิกในองค์ประกอบทุกครั้งที่แอตทริบิวต์ clickLink เปลี่ยนแปลงหรือไม่
toxaq

@toxaq มันไม่สมบูรณ์แบบแน่นอน ฉันสงสัยว่าเมื่อclickLinkแอตทริบิวต์เปลี่ยนไปคำสั่งจะเพิ่มตัวจัดการการคลิกใหม่ แต่ปล่อยให้เก่ามาแทนที่ ผลที่ได้อาจจะค่อนข้างวุ่นวาย เดิมทีฉันเขียนสิ่งนี้เพื่อใช้ในสถานการณ์ที่clickLinkคุณลักษณะจะไม่เปลี่ยนแปลงดังนั้นฉันจึงไม่ผูกจุดจบนี้ ฉันคิดว่าการแก้ไขข้อผิดพลาดนี้จะทำให้รหัสง่ายขึ้น - ฉันอาจลองทำเมื่อฉันมีเวลา (ฮ่า!)
Bennett McElwee

เย็น. ใช่ถ้าคุณนำชุดทดลองออกมา $ สังเกตุว่ามันจะใช้ได้ตามที่ตั้งใจไว้ ฉันจะวางรุ่นของฉันที่นี่ แต่จะไม่จัดรูปแบบในความคิดเห็นและเป็นแถบที่เหมือนกันในทางปฏิบัติส่วนที่สังเกต
toxaq

@toxaq ฉันได้แก้ไขโค้ดตอนนี้ ฉันคิดว่าฉันได้ดัดแปลงรหัสจากคำสั่งอื่น ๆ นั่นคือสาเหตุที่ไม่เหมาะสมattrs.$observeอยู่ที่นั่น ขอบคุณสำหรับคำแนะนำของคุณ
Bennett McElwee

กำลังจะแนะนำสิ่งนี้เมื่ออ่านคำตอบที่แนะนำ ทำความสะอาดและนำมาใช้ใหม่ +1
Dormouse

4

โปรดจำไว้ว่าหากคุณใช้ ng-click สำหรับการกำหนดเส้นทางคุณจะไม่สามารถคลิกขวาที่องค์ประกอบและเลือก 'เปิดในแท็บใหม่' หรือ ctrl คลิกลิงก์ ฉันพยายามใช้ ng-href เมื่ออยู่ในการนำทาง ng-click ดีกว่าที่จะใช้กับปุ่มสำหรับการใช้งานหรือเอฟเฟกต์ภาพเช่นการยุบ แต่เกี่ยวกับฉันจะไม่แนะนำ หากคุณเปลี่ยนเส้นทางคุณอาจต้องเปลี่ยนเส้นทางเป็นจำนวนมากในแอปพลิเคชัน มีวิธีการคืนลิงค์ เช่นเกี่ยวกับ วิธีนี้คุณวางไว้ในยูทิลิตี้


1

ผมใช้ng-clickคำสั่งที่จะเรียกฟังก์ชั่นในขณะที่ขอเส้นทาง templateUrl, ที่จะตัดสินใจว่า<div>จะเป็นมีshowหรือhideเส้นทางภายในหน้า templateUrl หรือสำหรับสถานการณ์ที่แตกต่างกัน

AngularJS 1.6.9

ให้ดูตัวอย่างเมื่ออยู่ในหน้าการเราต์ฉันต้องการการเพิ่ม<div>หรือการแก้ไข<div>ซึ่งฉันควบคุมโดยใช้โมเดลคอนโทรลเลอร์หลัก$scope.addProductและ$scope.editProductบูลีน

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(หน้าการกำหนดเส้นทาง) อยู่ในไดเรกทอรีเดียวกัน

หวังว่านี่จะช่วยใครซักคน


1

โซลูชันอื่น แต่ไม่ใช้ ng-click ซึ่งยังใช้ได้แม้กับแท็กอื่นที่ไม่ใช่<a>:

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

วิธีนี้คุณสามารถส่งพารามิเตอร์ไปยังเส้นทางของคุณ: https://stackoverflow.com/a/40045556/838494

(นี่เป็นวันแรกของฉันที่มีเชิงมุมยินดีต้อนรับข้อเสนอแนะที่อ่อนโยน)


0

คุณสามารถใช้ได้:

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

หากคุณต้องการตัวแปรแบบไดนามิกภายในhrefคุณสามารถทำเช่นนี้ได้:

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

ตำแหน่งที่ลิงก์เป็นตัวแปรขอบเขตเชิงมุม


5
นี่ไม่ได้ตอบคำถาม OP ซึ่งกำลังจะใช้ng-clickเพื่อเปลี่ยนตำแหน่ง
jjmontes

0

เพียงทำดังต่อไปนี้ในการเขียน html ของคุณ:

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

และในตัวควบคุมของคุณเพิ่ม $ state ดังนี้:

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

$scope.going = function(){

$state.go('your route');

}

})
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.