Подтвердить что ты не робот

Использование ui-router с Bootstrap-ui modal

Я знаю, что это было рассмотрено много раз, и большинство статей относятся к этому фрагменту кода: Модальное окно с настраиваемым URL в AngularJS

Но я просто не понимаю. Я не считаю, что это очень ясно. Я также нашел этот jsfiddle, который был действительно отличным, очень полезным, за исключением того, что это не добавляет URL-адрес и позволяет мне использовать обратную для закрытия модального режима.


Изменить: мне нужна помощь.

Итак, позвольте мне попытаться объяснить, чего я пытаюсь достичь. У меня есть форма для добавления нового элемента, и у меня есть ссылка "Добавить новый элемент". Я хотел бы, когда я нажимаю "добавить новый элемент", модальный всплывает с формой, которую я создал "add-item.html". Это новое состояние, поэтому URL-адрес изменяется на /add -item. Я могу заполнить форму, а затем выбрать сохранить или закрыть. Закрыть, закрывает модальный: p (как нечетно). Но я также могу щелкнуть назад, чтобы закрыть модальный, и вернуться на предыдущую страницу (состояние). Мне не нужна помощь с Close в этот момент, поскольку я все еще борется с тем, чтобы на самом деле получить модальную работу.


Это мой код в его нынешнем виде:

Контроллер навигации: (это даже правильное место для размещения модальных функций?)

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>

нового 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>

Кроме того, пока он открывает модальный режим, он не закрывает его, так как я не мог этого сделать.

4b9b3361

Ответ 1

Интуитивно думать о модальном как компоненте представления состояния. Возьмите определение состояния с шаблоном вида, контроллером и, возможно, некоторым решением. Каждая из этих функций также относится к определению модальности. Сделайте еще один шаг и привяжите запись состояния к открытию модального и выходного состояния для закрытия модального кода, и если вы можете инкапсулировать всю сантехнику, тогда у вас есть механизм, который можно использовать точно так же, как состояние с ui-sref или $state.go для входа и кнопки "Назад" или более модальных триггеров для выхода.

Я довольно внимательно изучил этот , и мой подход заключался в создании поставщика модального состояния, который можно было бы использовать аналогично $stateProvider, когда конфигурирование модуля для определения состояний, связанных с модалами. В то время меня особенно интересовало объединение контроля над модальным увольнением через государственные и модальные события, которые усложняются, чем то, о чем вы просите, так что вот упрощенный пример.

Ключ делает модальным ответственность за состояние и использует крючки, которые модальные обеспечивают, чтобы синхронизировать состояние с независимыми взаимодействиями, поддерживающими модальную поддержку через область действия или ее пользовательский интерфейс.

.provider('modalState', function($stateProvider) {
    var provider = this;
    this.$get = function() {
        return provider;
    }
    this.state = function(stateName, options) {
        var modalInstance;
        $stateProvider.state(stateName, {
            url: options.url,
            onEnter: function($modal, $state) {
                modalInstance = $modal.open(options);
                modalInstance.result['finally'](function() {
                    modalInstance = null;
                    if ($state.$current.name === stateName) {
                        $state.go('^');
                    }
                });
            },
            onExit: function() {
                if (modalInstance) {
                    modalInstance.close();
                }
            }
        });
    };
})

Ввод состояния запускает модальный. Государственный выход закрывает его. Модальная может закрыться сама по себе (например: через фоновый клик), поэтому вы должны наблюдать это и обновлять состояние.

Преимущество этого подхода в том, что ваше приложение продолжает взаимодействовать в основном с государствами и концепциями, связанными с государством. Если позже вы решите превратить модальный в обычный вид или наоборот, тогда очень мало кода необходимо изменить.

Ответ 2

Вот provider, который улучшает решение @nathan-williams, передавая раздел resolve до 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: {
        ...
      }
    })
}]);

Ответ 4

Сам $modal не имеет функции close(), я имею в виду If you console.log($ modal). Вы можете видеть, что есть только функция open().

Закрытие модальности зависит от объекта $modalInstance, который вы можете использовать в своем modalController.

Итак, это: $modal.close(результат) на самом деле не функция!

Примечание:             console.log($ модальный);             == → результат:

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

Есть какой-то способ решить эту проблему, один из способов:

Сначала вы должны определить контроллер в своем модальном виде следующим образом:

   $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

   });