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では、ボタンがクリックされたときにAboutページに移動したいとします。一つの方法は

<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(hash); できます。これは、@ seanが別の返信で提案していますが、何らかの理由で投票数がはるかに少なくなっています。
Quested Aronssonによる2013

2
@PerQuestedAronsson pathhash2つの異なる目的を果たしますが、状況によっては同じ効果があります。ほとんどの場合、厳密なルーティング(特にhtml5mode有効にした場合)はpath、正規の選択になります。これを反映するように答えを更新しました。
Josh David Miller

2
@DavidWoodsこれは機能するはずですが、ベースパスが一致する場合のみです/。からアプリを提供している場合/app/index.html、絶対URLはであるため、これは機能しません/app/next.html。明らかに、サーバーはでindex.htmlヒットし/next.htmlたときにファイルを返すように設定する必要があります。あなたが私に見てもらいたいなら、プランカー/フィドルを投稿してください。
Josh David Miller

2
これは、非常に一般的で役立つことです。それを集中化する方法はありgoますか、それともすべてのコントローラーにメソッドを追加する必要がありますか?(または、goメソッドを使用してルートコントローラーを作成しますか?)
Bennett McElwee 2013

3
@BennettMcElwee私は断然最良のアプローチはアンカータグを使用することだと思います。この場合、ボタンタグは値を提供せず、問題を引き起こしています。つまり、次のようなディレクティブを簡単に作成できます<button click-go="/home">Click</button>。リンク機能はこれだけのようになります。element.on("click", function () { $location.path(attrs.clickGo); });
ジョシュ・デイヴィッド・ミラー

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 2013

8
これは、このページで実際に機能した唯一の推奨ソリューションです。別の答えがなぜこれよりもはるかに多くの票を持つのかわからない。
Quested Aronssonによる2013

私はこれを試しましたが、うまくいきません。コントローラに接続する前に、モジュールにも場所を追加する必要がありますか?
Fallenreaper 2016年

<a>ではなくdivにng-clickを設定すると、これは私にとってはうまくいきました。
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 2013年

@toxaq完璧ではありません。私はときと思われるclickLink属性が変化し、ディレクティブは新しいクリックハンドラを追加しますが、代わりに古いものを残します。結果は少し混乱するかもしれません。私はもともと、clickLink属性が変更されない状況で使用するためにこれを書いたので、この緩い目的を縛ることはありませんでした。このバグを修正することで、実際にはより単純なコードにつながると思います-時間があるときに(ha!)
Bennett McElwee

涼しい。ええ、attrs。$ observeを削除すると、意図したとおりに機能します。ここに自分のバージョンを貼り付けますが、コメントでフォーマットされず、観察部分と実質的に同じです。
toxaq 2013年

@toxaqコードを編集しました。私は他のいくつかのディレクティブからのコードを適合させたと思います、それが不適切attrs.$observeがそこにあった理由です。あなたの提案をありがとう。
Bennett McElwee

提案された回答を読むときに、これを提案しようとしていました。クリーンで再利用可能。+1
2014

4

ルーティングにng-clickを使用する場合、要素を右クリックして[新しいタブで開く]またはリンクをクリックするctrlを選択できないことに注意してください。ナビゲーションに関しては、ng-hrefを使用するようにしています。ng-clickは、操作や折りたたみなどの視覚効果のボタンで使用する方が適切です。しかし、私はお勧めしません。ルートを変更した場合、アプリケーションに配置された多くの場所を変更する必要がある場合があります。リンクを返すメソッドを用意します。例:について。このメソッドをユーティリティに配置します


1

ng-clickディレクティブを使用して関数を呼び出しながら、ルートtemplateUrlを要求しているときに、ルートtemplateUrlページ内<div>にあるshowか、またはhideルートテンプレートUrlページ内にあるか、またはさまざまなシナリオに対応するかを決定しました。

AngularJS 1.6.9

例を見てみましょう。ルーティングページで、親コントローラーモデルとブール値を使用して制御<div>するadd またはedit が必要です。<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(ルーティングページ)は同じディレクトリにあり、

これが誰かを助けることを願っています。



0

以下を使用できます。

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

href内に動的変数が必要な場合は、次のようにすることができます。

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

ここで、リンクはAngularスコープ変数です。


5
これは、ng-click場所の変更に使用することに関するOPの質問には答えません。
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.