web-dev-qa-db-ja.com

Angular UI Bootstrapでモーダルフォームと非モーダルフォームに同じコントローラーを使用する方法は?

登録フォーム付きのモーダルを持っています。同じフォームがモーダルではなく、ランディングページの下部に表示されます。

現在、登録モーダルを処理する私のコントローラーは、_$modalInstance_などのパラメーターの1つとして_$scope_を受け取ります。_ng-controller="SignUpCtrl"_をランディングページの要素に追加すると、コントローラは_$modal.open_メソッドを介して作成されなかったため、Angularは_Unknown provider: $modalInstanceProvider <- $modalInstance_について不平を言います。

ユーザーを登録するためのサービス(authService.signUp(data).then/catch...))がありますが、コントローラー自体がもう少し機能します-入力の処理、イベントの発行(翻訳されたエラーメッセージなど)、Cookieの設定など。

ほとんどすべてのコントローラーコードを複製せずに、このようなケースを処理する最良の方法は何ですか?コードをコントローラーからさらに別のより高レベルのサービスに移動する必要がありますか?

24
szimek

長い間苦労した後、私はコントローラーをモーダルと通常の両方のケースで再利用する簡単なトリックを見つけました。

呼び出し元のスコープをモーダルコントローラーに渡すことができることがわかったので、modalInstanceを$ scopeにプッシュして、モーダルコントローラーに渡しました。 $ scopeはよく知られているため、プロバイダーの問題は不明です。

以下に例を示します。

CallerController = function($rootScope, ...) {
   var modalScope = $rootScope.$new();
   modalScope.modalInstance = $modal.open({
        templateUrl: tempUrl,
        controller: ReusableModalController,
        scope: modalScope // <- This is it!
    });

    modalScope.modalInstance.result.then(function (result) {
        // Closed
    }, function () {
        // Dismissed
    });
};

ReusableModalController = function($scope, ...){
    var dataToSendBack = 'Hello World';
    $scope.modalInstance.close(dataToSendBack);
};

乾杯!

27
KinoP

Ui-routerを使用している場合は、ui-routerからのresolveを使用して$ uibModalInstanceを提供できます(以前は$ modalInstanceでした)。

$stateProvider
.state('conductReview', {
    url: '/review',
    templateUrl: '/js/templates/review.html',
    controller: 'yourController',
    resolve: {
        $uibModalInstance: function () { return null; } // <- workaround if you want to use $uibModalInstance in your controller.
    }
})

そうすれば、通常のコントローラーのようにモーダルコントローラーを使用できます。コントローラーに$ uibModalInstanceを挿入すると、nullになります。

6
Thomas

モーダルフォームとランディングページフォームの両方に同じコントローラーを使用する場合は、

modalInstance.result.then(function (selectedItem) { $scope.selected = selectedItem; }, function () { $log.info('Modal dismissed at: ' + new Date()); });

selectedItemのモーダルフォームからすべてのデータを取得し、これをランディングページフォームで使用できます。また、どのようにしてモーダルを開きますか。ボタンを使用する場合は、$modal.openを使用してそのng-modelをモーダルを開くようにバインドします。モーダル用に個別のコントローラーを作成しないでください。ランディングページと同じコントローラーを使用します。このようにして、1つのコントローラーを使用して、モーダルを閉じた後、モーダルと他の関数を開くことができます。

PS:ここで指定されているコードスニペットは angular uiのページ からのものです。そのページのドキュメントでselectedItemを確認してください

0
Aniket Sinha