2017-05-06 2 views
0

Modalを開くアプリケーションにボタンがあります。このモーダルは、UIルート状態で新しいURLに反して設定されます。AngularJS:UIルーターモーダル - 親スコープ

モーダルコントローラでは、親$スコープにアクセスする必要があります。親$ scopeには、todolist.addという子状態でアクセスする必要のある配列があります。

なぜ親の$ scopeにアクセスする必要がありますか?なぜなら、サーバーを再度呼び出さずに親の$ scopeデータを操作したいからです。

UIルータの親スコープにアクセスする最も良い方法は何ですか?

// routes 

$stateProvider 
      .state('todolist', { 
       url: '/todo-list', 
       views: { 
        '@': { 
         ..., 
         controller: 'ListsController' 
        } 
       } 
      }) 
      .state('todolist.add', { 
       url: '/list/add', 
       onEnter: ['$state', '$uibModal', function ($state, $uibModal) { 
        $uibModal.open({ 
         ..., 
         controller: 'FormListModalController' // <- in this controller I need to access the $scope from the parent 
        }).result.finally(function() { 
         ... 
        }); 
       }] 
      })... 

.controller('ListsController', function ($scope, ...) { 
     $scope.lists = []; // there are data in this $scope array 
    }); 

.controller('FormListModalController', function ($scope, ...) { 
     $scope.$parent.todolist.lists; // <- in this Modal's Ctrl I need to access the parent $scope (ListsController) 
    }); 
+0

https://toddmotto.com/all- about-angulars-emit-broadcast-on-publish-subscribe/ 私は、イベントをブロードキャストして親スコープでそれを聞くのが最善の方法の1つだと思います。 また、サービスでデータを操作した後、イベントをブロードキャストしてコントローラにデータを再度提供させることを検討してください。 – Alburkerk

答えて

1

あなたがしようとしていることは、実際には機能しません。あなたの 'todolist.add'状態コントローラはあなたのモーダル(ポップアップ)コントローラと共有されていないためです。あなたの場合、 'todolist.add'には空のコントローラがあり、あなたのモーダルインスタンス化されたonEnterはFormListModalControllerコントローラを使用します。

SOLUTION 1:親状態 - >子状態 - >モーダル:STATE PARAMS +は

を解決する私は、2つの状態とモーダル間の$範囲からのデータコピーを行うことによって、これを解決しました。

サンプルの下に見つけてください:

  • ホームが親コントローラであると
  • home.popup TOCOPYという変数を持っているがポップアップを開く子状態です

    angular.module('test', [ 'ui.bootstrap', 'ui.router' ]); 
    
    angular.module('test').config(['$stateProvider', '$urlRouterProvider', 
        function($stateProvider, $urlRouterProvider, $stickyStateProvider, $locationProvider) { 
         $urlRouterProvider.otherwise("/home"); 
    
         $stateProvider 
         .state('home', { 
          url     : '/home', 
          templateUrl   : './home.html', 
          controller   : 'homeController' 
         }) 
         .state('home.popup', { 
          url     : '/popup', 
          params    : {tocopy: null}, 
          onEnter: ['$state', '$stateParams', '$uibModal', function ($state, $stateParams, $uibModal) { 
           $uibModal.open({ 
            templateUrl: './popup.html', 
            controller: 'popupController', 
            resolve: { 
             tocopy: function() { 
              return $stateParams.tocopy; 
             } 
            } 
            }).result.finally(function() { 
             $state.go('^'); 
            }); 
          }] 
         }) 
    }]); 
    
    angular.module('test').controller('homeController', function($scope, $state) { 
        $scope.tocopy = "hello"; 
    
        $scope.openPopup = function() { 
         $state.go('home.popup', { tocopy: $scope.tocopy}); 
        }; 
    
    }); 
    angular.module('test').controller('popupController', function($scope, $state, tocopy) { 
        $scope.tocopy = tocopy; 
    }); 
    

トリックは使用:

  • paramsは状態別
  • の状態から変数を渡す
  • 解決コントローラ

溶液2モーダルする状態から変数を渡す:ストレージサービスを

大きなデータセットの場合、他の解決策は、データをサービスに格納することにあります。どのコントローラーからもアクセス可能。

angular.module('test', [ 'ui.bootstrap', 'ui.router' ]); 

angular.module('test').config(['$stateProvider', '$urlRouterProvider', 
    function($stateProvider, $urlRouterProvider, $stickyStateProvider, $locationProvider) { 
     $urlRouterProvider.otherwise("/home"); 

     $stateProvider 
     /******************************************************* 
     * HOME 
     *******************************************************/ 
     .state('home', { 
      url     : '/home', 
      templateUrl   : './home.html', 
      controller   : 'homeController' 
     }) 
     .state('home.popup', { 
      url     : '/popup', 
      onEnter: ['$state', '$stateParams', '$uibModal', function ($state, $stateParams, $uibModal) { 
       $uibModal.open({ 
        templateUrl : './popup.html', 
        controller : 'popupController', 
        windowClass : 'center-modal' 
       }).result.finally(function() { 
        $state.go('^'); 
       }); 
      }] 
     }) 
}]); 

angular.module('test').service('storageService', function() { 
     var data; 

     return { 
      getData: function() { return data; }, 
      setData: function(value) { data = value; } 
     }; 
}); 

angular.module('test').controller('homeController', function($scope, $state, storageService) { 
    $scope.tocopy = "hello"; 

    $scope.openPopup = function() { 
     storageService.setData($scope.tocopy); 
     $state.go('home.popup'); 
    }; 

}); 
angular.module('test').controller('popupController', function($scope, $state, storageService) { 
    $scope.tocopy = storageService.getData(); 
}); 

例: enter image description here

コード: あなたが見てみたい場合、私はGitHubの中に私の例をプッシュ:https://github.com/gjeanmart/stackexchange/tree/master/43823794

+0

巨大な配列をparamsに渡すのは良い解決策ですか? – Victor

+0

2番目のソリューションを追加しました。巨大なデータセットの場合、実際にはデータをローカルAngularサービスに格納することをお勧めします(ソリューション2を参照)。 –

関連する問題