8

イライラする朝を迎えています。

私はベースの場所を持つアプリを持っているので、頭の中は<base href="/my/path/fruits/index.html" />. function を介してページングをセットアップしようとしていますnextPage()。をトリガーするリンクをクリックするとnextPage()、 を使用します$location.path('/page/:page')

予想される動作:ブラウザの場所の URL が に変わるはずhttp://localhost/my/path/fruits/page/2です。

実際の動作:ブラウザの URL が (ごく短時間) に変わりhttp://localhost/my/path/fruits/page/2、その後 に戻りますhttp://localhost/my/path/fruits/

: ベース ロケーションを使用していない場合、この動作は発生しないようです。ただし、アプリはサーバーの sub/sub/sub ディレクトリにあるため、ベースの場所を使用する必要があります。

また、 を設定すると、この動作は発生しません$locationProvider.html5Mode(false)

私は何か間違ったことをしていますか?これは Angular のバグですか? どんな助けでも大歓迎です。

適切なファイルは次のとおりです。

index.html:

<!doctype html>
<html ng-app="fruits">
  <head>
    <base href="/my/path/fruits/index.html" />
    <script src="angular.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="MainCntl">
      <div ng-view></div>
    </div>
  </body>
</html>

script.js:

angular.module('fruits', [], function($routeProvider, $locationProvider) {
    $routeProvider
    .when('/', {
        templateUrl: 'fruits.html',
        controller: FruitCntl,
    })
    .when('/page/:page', {
        templateUrl: 'fruits.html',
        controller: FruitCntl,
    })
    .otherwise({redirectTo:'/'})
    ;

    // configure html5 
    $locationProvider.html5Mode(true).hashPrefix('!');
}).filter('startFrom', function() 
    {
        return function(input, start) 
        {
            start = +start; //parse to int
            if (input == undefined){
                input = [];
            }
            return input.slice(start);
        }
})
;

function MainCntl($scope,$location){
    angular.extend($scope,{
        current_page: 1,
        per_page: 3,
        fruits: [
            {name: 'Apples', color: 'red'},
            {name: 'Bananas', color: 'yellow'},
            {name: 'Oranges', color: 'orange'},
            {name: 'Grapes', color: 'purple'},
            {name: 'Blueberries', color: 'blue'},
            {name: 'Strawberries', color: 'red'},
            {name: 'Raspberries', color: 'red'},
            {name: 'Clementines', color: 'orange'},
            {name: 'Pears', color: 'green'},
            {name: 'Mangoes', color: 'orange'}
        ],

        nextPage: function(){
            this.current_page++;
            $location.path('/page/'+this.current_page);
        },

        previousPage: function(){
            this.current_page--;
            $location.path('/page/'+this.current_page);
        }
    })
    $scope.total_pages = Math.ceil($scope.fruits.length / $scope.per_page);
}

function FruitCntl($scope,$location,$routeParams){
    if ($routeParams.page != undefined){
        $scope.current_page = $routeParams.page;
    }
}

fruit.html (ビュー)

Page: <a ng-click="previousPage()" ng-show="current_page > 1">Previous</a> {{current_page}} of {{total_pages}} <a ng-click="nextPage()" ng-show="current_page < total_pages">Next</a>
<div ng-repeat="fruit in fruits | startFrom:(current_page - 1)*per_page | limitTo:per_page">
    {{fruit.name}} are {{fruit.color}}<br/>
</div>
4

3 に答える 3

9

私は同じ問題を抱えていて、何がうまくいかなかったのか一生理解できませんでした。私にとってうまくいったのは、ng-clickイベントが代わりにボタンタグに添付されたアンカータグを変更することでした。私が収集できることから、デフォルトのアクションを防ぐために href 属性が指定されていない場合、Angular はアンカー タグの動作を変更するため、ng-click イベント ハンドラーで場所を手動で更新すると干渉する可能性があります。これは私の推測にすぎませんので、誰かがよりよく説明できることを願っています。

于 2012-11-24T13:46:08.967 に答える
5

URL の変更が 2 回発生するため、ブラウザーのロールバックが発生しています。ng-click 関数がトリガーされたときと、タグのデフォルトのブラウザー動作が発生したときに 1 回です。

そのため、URL/ビューに更新が表示され、元の状態に戻ります。

これは、ブラウザが実行すべきことを理解しているためです。

可能な解決策:

ボタンのソリューション ボタン で ng-click をトリガーする前に提案したように、ボタンには URL を更新する意味のある href 属性がないため、これは機能します。ボタンに href を追加できますが、何もしません。

タグ: ng-click で更新を行う代わりに、関数の使用を避け、href に URL を変更するロジックを実行させます。URL を更新するタグのデフォルトの動作をブラウザーに実行させるため、よりクリーンなソリューションです。

このようにすることの利点は、誰でも一目で URL スキームを理解できるため、コードの保守が容易になることです。

<a href="#/go/to/logic/5">Update to logic 5</a>

ng-click を含むタグ: プログラムで変更を行う必要がある場合は、タグのデフォルトの動作を避ける必要があります。

jQuery では、クリック イベントにバインドし、event.preventDefault() を実行してから、カスタム ロジックを実行します。

AngularJS の方法は、フレームワークが強制するロジックの分離のために少し異なります。したがって、これを解決する方法は、preventDefault を実行するディレクティブを作成することです。


IgnoreClick ディレクティブ.js

angularModule.directive('ignoreClick',  function() {

    return {
        restrict: 'A',
        link: function(scope, element) {
            element.bind('click', function(event) {
                event.preventDefault();
            });
        }
    }
});

使用例

<a href=”http://stackoverflow.com/” ignore-click=”ignore-click” ng-click=”whatever()”&gt;Don't Go</a>
于 2013-06-10T18:21:47.377 に答える
0

なぜこのように機能するのか、それとも簡単に再現できなかったのでこれがバグなのか (基本パスを意味します) についての質問に対する直接的な回答ではないかもしれませんが、解決策を提案します。

次のように、 reloadOnSearch: falseパラメータと一緒に表示するページを示すために url change を使用する代わりに、?page=4 のような urlパラメータを使用するようにしてください。

 $routeProvider
    .when('/', {
        templateUrl: 'fruits.html',
        controller: FruitCntl,
        reloadOnSearch: false
    })
    .otherwise({redirectTo:'/'})

あなたの場合、ルートは1つだけで十分だと思います。ここで、($location.path ではなく) $location からの検索機能を使用するようにページング ロジックを変更する必要があります。

$location.search('page', this.current_page);

このようにして、ページを変更するたびに新しいコントローラーを作成せずにページを更新します。また、ルーティング ロジックが簡素化されます。それが役立つことを願っています!

注: $locationProvider.html5Mode(true).hashPrefix('!');を削除する必要がありました。ローカルで実行するとサイトが壊れるため。

于 2012-11-22T20:07:46.787 に答える