web-dev-qa-db-ja.com

anglejs ui-routerの状態間で$ scopeデータを共有するにはどうすればよいですか?

親コントローラーでサービスを使用したりウォッチャーを構築したりせずに、メインコントローラーの$scopeへのアクセスを子の状態に与えるにはどうすればよいでしょうか。

  .state("main", {
      controller:'mainController',
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.1", {
      controller:'mainController',
      parent: 'main',
      url:"/1",
      templateUrl: 'form_1.html'
  })  
  .state("main.2", {
      controller:'mainController',
      parent: 'main',
      url: "/2",
      templateUrl: 'form_2.html'
  })  

子状態でmainControllerスコープにアクセスすることはできません-むしろ、望んでいるものではなく、そのスコープの別のインスタンスを取得しています。シンプルなものが足りないと感じています。状態オブジェクトには共有データ設定オプションがありますが、これをこのようなものに使用すべきかどうかはわかりません。

71
sjt003

I ワーキングプランカーを作成$scopeおよびUI-Routerの使用方法を示します。

状態の定義は変更されていません。

$stateProvider
    // States
 .state("main", {
      controller:'mainController',
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.1", {
      controller:'mainController',
      parent: 'main',
      url:"/1",
      templateUrl: 'form_1.html'
  })  
  .state("main.2", {
      controller:'mainController',
      parent: 'main',
      url: "/2",
      templateUrl: 'form_2.html'
  })  

ただし、各状態に異なるコントローラーを設定できます。どうして?各stateの各viewは、定義されたnewcontrollerinstanceを取得するためです。したがって、以下のようなmainControllerがありますが、状態'main.2'にナビゲートすると、2回インスタンス化されます。

controller('mainController', function ($scope) {
  $scope.Model = $scope.Model || {Name : "xxx"};
})

しかし、私たちが見ることができるのは、 here$scope.Modelが既に存在するかどうかをチェックすることであり、そうでない場合は(親状態)でインスタンス化します新しいインスタンス{Name : "xxx"}.

さて、私が言っているのは、親状態のみが$scope.Modelを初期化するということです。他のすべての人はすでにそれを満たしています。どうやって?答えは次のとおりです。

ビュー階層によるスコープの継承のみ

スコープのプロパティは、状態のビューがネストされている場合にのみ状態チェーンを継承することに注意してください。スコーププロパティの継承は、状態のネストやビュー(テンプレート)のネストとは関係ありません。

サイト内のネストされていないさまざまな場所でテンプレートがUIビューを生成するネストされた状態を持つことは完全に可能です。このシナリオでは、子状態のビュー内で親状態ビューのスコープ変数にアクセスすることは期待できません。

そのため、ドキュメントに記載されているとおり。子ビューは親ビューにネストされているため、スコープは継承されます。

スコープの理解

AngularJSでは、子スコープは通常、親スコープからプロトタイプ的に継承されます。
...

「。」モデル内でプロトタイプの継承が機能することを保証します。

// So, use
<input type="text" ng-model="someObj.prop1"> 
// rather than
<input type="text" ng-model="prop1">.

以上です。 UI-Routerビューとangularスコープから継承を取得します。これは、参照型(Model)をスマートに使用したためです。つまり、'.'ng-model定義のドット-データを共有できるようになりました

注:ドット「。」を含むng-model="Model.PropertyNameには、referenceオブジェクトModel {}といくつかのプロパティがあることを意味します:PropertyName

ここでの作業例 を確認してください

107
Radim Köhler

$ rootScope でスコープ全体を取得できます。スコープの一部だけが必要な場合、ui-routerには カスタムデータ 機能があります。

マルチステップフォームの作成方法は次のとおりです。フローのステップに関する情報を含むルートが必要でした。

まず、UIルーターを使用したルートがいくつかあります。

  // Sign UP routes
  .state('sign-up', {
    abstract: true,
    url: '/sign-up',
    controller: 'SignupController',
    templateUrl: 'sign-up/index.html',
  })
  .state('sign-up.start', {
    url: '-start',
    templateUrl: 'sign-up/sign-up.start.html',
    data: { step: 0, title: 'Welcome to Mars!', },
  })
  .state('sign-up.expertise', {
    url: '-expertise',
    templateUrl: 'sign-up/sign-up.expertise.html',
    data: { step: 1, title: 'Your Expertise'},
  })

通知:

  • 各ルートのdata要素。
  • abstract状態にはSignupControllerがあります。これがこのマルチステップフォームの唯一のコントローラーです。 abstractは必須ではありませんが、このユースケースでは意味があります。

SignupController.js

angular.module('app').controller('SignupController', function($scope, $state) {
  $scope.state = $state;
});

ここで、ui-routerの$stateを取得し、$scopeに配置します

メインテンプレート「sign-up/index.html」は次のとおりです。

<h2>{{state.current.data.title}}</h2>

<div>This is a multi-step-progress control {{state.current.data.step}}</div>

<form id="signUpForm" name="signUpForm" novalidate>
  <div ui-view></div>
</form>

子テンプレートは好きなものにすることができます。

15
Michael Cole

考え方は、親から子への継承でスコープを使用することです:

 .state("main", {
      controller:'mainController',
      abstract: true,
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.1", {
      controller:'mainController1',
      parent: 'main',
      url:"/1",
      templateUrl: 'form_1.html'
  })  
  .state("main.2", {
      controller:'mainController2',
      parent: 'main',
      url: "/2",
      templateUrl: 'form_2.html'
  })  

使い方が簡単であるよりも、3つのコントローラーがあり、1つは共有され(mainController)、各ビューには独自のコントローラーがあります。

9
Ben Diamant

ネストされたビューを使用している場合は、他のコントローラーを記述しないでください。この方法により、同じコントローラーデータを共有します。

.state("main", {
            url: "/main",
            templateUrl: "templates/Ders",
            controller: "DersController as DersC"
       }).state("main.child1", {
            url: "/child1",
            templateUrl: "templates/Ders/child1"
       }).state("main.child2", {
            url: "/child2",
            templateUrl: "templates/Ders/child2"
        })
7

シェア変数をすべてのコントローラーでアクセスできるサービスにグループ化する最も簡単なソリューションではありませんか? ...

1
hugsbrugs