web-dev-qa-db-ja.com

Bootstrap-uiモーダルでのui-routerの使用

私はこれが何度も取り上げられており、ほとんどの記事が次のコードを参照していることを知っています: AngularJSのカスタムURLを持つモーダルウィンドウ

しかし、私はそれを取得しません。私はそれがまったく明確であるとは思わない。また、これを見つけました jsfiddle これはURLを追加せず、戻るボタンを使用してモーダルを閉じることができることを除いて、実際に非常に役立ちました。


編集:これは私が助けを必要としているものです。

だから、私が達成しようとしていることを説明してみましょう。新しいアイテムを追加するフォームがあり、「新しいアイテムを追加」リンクがあります。 「新しいアイテムを追加」をクリックすると、「add-item.html」を作成したフォームでモーダルがポップアップします。これは新しい状態なので、URLは/ add-itemに変わります。フォームに入力して、保存するか閉じるかを選択できます。閉じる、モーダルを閉じます:p(奇数)。ただし、戻るボタンをクリックしてモーダルも閉じ、前のページ(状態)に戻ることもできます。実際にモーダルを動作させるのに苦労しています。


これは私のコードです:

Navigation Controller:(モーダル機能を配置するのに正しい場所ですか?)

angular.module('cbuiRouterApp')
  .controller('NavbarCtrl', function ($scope, $location, Auth, $modal) {
    $scope.menu = [{
      'title': 'Home',
      'link': '/'
    }];

    $scope.open = function(){

        // open modal whithout changing url
        $modal.open({
          templateUrl: 'components/new-item/new-item.html'
        });

        // I need to open popup via $state.go or something like this
        $scope.close = function(result){
          $modal.close(result);
        };
      };

    $scope.isCollapsed = true;
    $scope.isLoggedIn = Auth.isLoggedIn;
    $scope.isAdmin = Auth.isAdmin;
    $scope.getCurrentUser = Auth.getCurrentUser;

    $scope.logout = function() {
      Auth.logout();
      $location.path('/login');
    };

    $scope.isActive = function(route) {
      return route === $location.path();
    };
  });

これは私がモーダルをアクティブにする方法です:

 <li ng-show='isLoggedIn()' ng-class='{active: isActive("/new-item")}'>
   <a href='javascript: void 0;' ng-click='open()'>New Item</a>
 </li>

new-item.html:

<div class="modal-header">
  <h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
  <ul>
    <li ng-repeat="item in items"><a ng-click="selected.item = item">{{ item }}</a></li>
  </ul>Selected:<b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
  <button ng-click="ok()" class="btn btn-primary">OK</button>
  <button ng-click="close()" class="btn btn-primary">OK</button>
</div>

また、これはモーダルを開きますが、それを解決することができなかったため、モーダルを閉じません。

31
Daimz

providerセクションをresolveに渡すことで@ nathan-williamsソリューションを改善するcontrollerは次のとおりです。

.provider('modalState', ['$stateProvider', function($stateProvider) {
  var provider = this;

  this.$get = function() {
    return provider;
  }

  this.state = function(stateName, options) {
    var modalInstance;

    options.onEnter = onEnter;
    options.onExit = onExit;
    if (!options.resolve) options.resolve = [];

    var resolveKeys = angular.isArray(options.resolve) ? options.resolve : Object.keys(options.resolve);
    $stateProvider.state(stateName, omit(options, ['template', 'templateUrl', 'controller', 'controllerAs']));

    onEnter.$inject = ['$uibModal', '$state', '$timeout'].concat(resolveKeys);
    function onEnter($modal, $state, $timeout) {
      options.resolve = {};

      for (var i = onEnter.$inject.length - resolveKeys.length; i < onEnter.$inject.length; i++) {
        (function(key, val) {
          options.resolve[key] = function() { return val }
        })(onEnter.$inject[i], arguments[i]);
      }

      $timeout(function() { // to let populate $stateParams
        modalInstance = $modal.open(options);
        modalInstance.result.finally(function() {
          $timeout(function() { // to let populate $state.$current
            if ($state.$current.name === stateName)
              $state.go(options.parent || '^');
          });
        });
      });
    }

    function onExit() {
      if (modalInstance)
        modalInstance.close();
    }

    return provider;
  }
}]);

function omit(object, forbidenKeys) {
  var prunedObject = {};
  for (var key in object)
    if (forbidenKeys.indexOf(key) === -1)
      prunedObject[key] = object[key];
  return prunedObject;
}

それをそのように使用します:

.config(['modalStateProvider', function(modalStateProvider) {
  modalStateProvider
    .state('...', {
      url: '...',
      templateUrl: '...',
      controller: '...',
      resolve: {
        ...
      }
    })
}]);
7
Dawid Grzesiak

私は同様の質問に答え、ここに例を提供しました:

AngularJSのカスタムURLを使用したモーダルウィンドウ

完全に機能するHTMLとplunkerへのリンクがあります。

2
cornernote

$ modal自体にはclose()funcftionがありません。つまり、console.log($ modal)の場合、open()関数だけがあることがわかります。

モーダルを閉じるには、modalControllerで使用できる$ modalInstanceオブジェクトに依存します。

だからこれ:$ modal.close(result)は実際には関数ではありません!

注意:console.log($ modal); == >>結果:

          Object { open: a.$get</k.open() }
           // see ? just open ! , no close !

これを解決する方法がいくつかあります。1つの方法は次のとおりです。

まず、モーダルで次のようにコントローラーを定義する必要があります。

   $modal.open({
      templateUrl: 'components/new-item/new-item.html',
      controller:"MyModalController"
    });

そして、その後、

    app.controller('MyModalController',function($scope,$modalInstance){
      $scope.closeMyModal = function(){
       $modalInstance.close(result);
        }
       // Notice that, This $scope is a seperate scope from your NavbarCtrl,
       // If you want to have that scope here you must resolve it

   });
0
Milad