1. ホーム
  2. angularjs

[解決済み] AngularJSでコントローラをリロードせずにパスを変更することはできますか?

2022-04-22 09:12:22

質問

以前にも質問されたことがあり、その回答を見る限りではあまり良い印象は受けません。このサンプルコードも参考にしながらお聞きしたいのですが・・・。

私のアプリは、それを提供するサービスで現在のアイテムをロードします。アイテムが再ロードされることなく、アイテムデータを操作するコントローラがいくつか存在します。

私のコントローラは、項目がまだ設定されていない場合は再ロードし、そうでない場合は、コントローラ間で、サービスから現在ロードされている項目を使用します。

問題点 : Item.htmlをリロードすることなく、コントローラごとに異なるパスを使用したい。

1) それは可能ですか?

2) それが不可能な場合、私がここで思いついたものと比べて、コントローラごとにパスを持つより良いアプローチはありますか?

app.js

var app = angular.module('myModule', []).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
      when('/items', {templateUrl: 'partials/items.html',   controller: ItemsCtrl}).
      when('/items/:itemId/foo', {templateUrl: 'partials/item.html', controller: ItemFooCtrl}).
      when('/items/:itemId/bar', {templateUrl: 'partials/item.html', controller: ItemBarCtrl}).
      otherwise({redirectTo: '/items'});
    }]);

アイテム.html

<!-- Menu -->
<a id="fooTab" my-active-directive="view.name" href="#/item/{{item.id}}/foo">Foo</a>
<a id="barTab" my-active-directive="view.name" href="#/item/{{item.id}}/bar">Bar</a>
<!-- Content -->
<div class="content" ng-include="" src="view.template"></div>

controller.js

// Helper function to load $scope.item if refresh or directly linked
function itemCtrlInit($scope, $routeParams, MyService) {
  $scope.item = MyService.currentItem;
  if (!$scope.item) {
    MyService.currentItem = MyService.get({itemId: $routeParams.itemId});
    $scope.item = MyService.currentItem;
  }
}
function itemFooCtrl($scope, $routeParams, MyService) {
  $scope.view = {name: 'foo', template: 'partials/itemFoo.html'};
  itemCtrlInit($scope, $routeParams, MyService);
}
function itemBarCtrl($scope, $routeParams, MyService) {
  $scope.view = {name: 'bar', template: 'partials/itemBar.html'};
  itemCtrlInit($scope, $routeParams, MyService);
}

解像度です。

ステータス : 受理された回答で推奨されているように検索クエリを使用することで、メインコントローラを再ロードすることなく、異なるURLを提供することができました。

app.js

var app = angular.module('myModule', []).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
      when('/items', {templateUrl: 'partials/items.html',   controller: ItemsCtrl}).
      when('/item/:itemId/', {templateUrl: 'partials/item.html', controller: ItemCtrl, reloadOnSearch: false}).
      otherwise({redirectTo: '/items'});
    }]);

アイテム.html

<!-- Menu -->
<dd id="fooTab" item-tab="view.name" ng-click="view = views.foo;"><a href="#/item/{{item.id}}/?view=foo">Foo</a></dd>
<dd id="barTab" item-tab="view.name" ng-click="view = views.bar;"><a href="#/item/{{item.id}}/?view=foo">Bar</a></dd>

<!-- Content -->
<div class="content" ng-include="" src="view.template"></div>

controller.js

function ItemCtrl($scope, $routeParams, Appts) {
  $scope.views = {
    foo: {name: 'foo', template: 'partials/itemFoo.html'},
    bar: {name: 'bar', template: 'partials/itemBar.html'},
  }
  $scope.view = $scope.views[$routeParams.view];
}

ディレクティブ.js

app.directive('itemTab', function(){
  return function(scope, elem, attrs) {
    scope.$watch(attrs.itemTab, function(val) {
      if (val+'Tab' == attrs.id) {
        elem.addClass('active');
      } else {
        elem.removeClass('active');
      }
    });
  }
});

私のパーシャルの中のコンテンツは ng-controller=...

どのように解決するのですか?

のようなURLを使用する必要がない場合。 #/item/{{item.id}}/foo#/item/{{item.id}}/bar けど #/item/{{item.id}}/?foo#/item/{{item.id}}/?bar の代わりに、ルートを設定することができます。 /item/{{item.id}}/ を持つこと reloadOnSearch 充てがう false ( https://docs.angularjs.org/api/ngRoute/provider/$routeProvider ) これは、URLの検索部分が変更されてもビューをリロードしないようにAngularJSに指示します。