webentwicklung-frage-antwort-db.com.de

Ui-router mit bootstrap-ui modal verwenden

Ich weiß, dass dies viele Male behandelt wurde, und die meisten Artikel beziehen sich auf diesen Code: Modal-Fenster mit benutzerdefinierter URL in AngularJS

Aber ich verstehe es einfach nicht. Ich finde das überhaupt nicht sehr klar. Ich fand auch diese jsfiddle , die wirklich toll war, sehr hilfreich, außer dass dies die URL nicht hinzufügt und ich die Rücktaste zum Schließen des Modals verwenden kann.


Edit: Hier brauche ich Hilfe.

Lassen Sie mich versuchen zu erklären, was ich erreichen möchte. Ich habe ein Formular, um ein neues Element hinzuzufügen, und ich habe einen Link "Neues Element hinzufügen". Ich möchte, wenn ich auf "Neues Element hinzufügen" klicke, ein Modal mit dem von mir erstellten Formular "add-item.html" angezeigt werden. Dies ist ein neuer Zustand, so dass sich die URL in /add-item. ändert. Ich kann das Formular ausfüllen und dann zum Speichern oder Schließen wählen. Schließen, schließt das Modal: p (wie ungerade). Ich kann aber auch auf "Zurück" klicken, um die Modalität zu schließen und zur vorherigen Seite zurückzukehren (Zustand).Zu diesem Zeitpunkt brauche ich keine Hilfe bei Close, da ich immer noch Probleme habe, den Modal-Modus zu erhalten.


Dies ist mein Code, wie er steht:

Navigationscontroller: (Ist dies auch der richtige Ort, um die Modalfunktionen einzusetzen?)

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();
    };
  });

So aktiviere ich den Modal:

 <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>

Auch wenn dies ein Modal öffnet, schließt es nicht, da ich das nicht herausfinden konnte.

30
Daimz

Es ist intuitiv, einen Modal als Ansichtskomponente eines Bundesstaates zu betrachten. Nehmen Sie eine Zustandsdefinition mit einer Ansichtsvorlage, einem Controller und möglicherweise einigen Auflösungen. Jede dieser Funktionen gilt auch für die Definition eines Modals. Gehen Sie noch einen Schritt weiter und verknüpfen Sie den Statuseintrag, um den Modal- und den State-Exit zu öffnen, und schließen Sie den Modalmodus. Wenn Sie alle Klempnerarbeiten kapseln können, haben Sie einen Mechanismus, der wie ein Zustand mit ui-sref oder $state.go für die Eingabe und die Option verwendet werden kann Zurück-Taste oder modal-spezifische Auslöser für das Beenden.

Ich habe dieses ziemlich ausführlich studiert und mein Ansatz bestand darin, einen modalen Zustandsanbieter zu erstellen, der analog zu $stateProvider verwendet werden kann, wenn ein Modul konfiguriert wird, um Zustände zu definieren, die an Modale gebunden sind. Zu dieser Zeit war ich besonders an der Vereinheitlichung der Kontrolle der modalen Entlassung durch Zustands- und Modalereignisse interessiert, die komplizierter wird als das, wonach Sie fragen, also hier ein vereinfachtes Beispiel .

Der Schlüssel besteht darin, den Modal in die Zuständigkeit des Zustands zu bringen und Hooks zu verwenden, die Modal zur Verfügung stellt, um den Zustand mit unabhängigen Interaktionen zu synchronisieren, die Modal über den Geltungsbereich oder seine Benutzeroberfläche unterstützt.

.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();
                }
            }
        });
    };
})

Staatseintrag startet den Modal. Staatsausgang schließt es. Der Modal wird möglicherweise von alleine geschlossen (z. B. über Hintergrundklick), daher müssen Sie dies beobachten und den Status aktualisieren.

Der Vorteil dieses Ansatzes ist, dass Ihre App weiterhin hauptsächlich mit Status und zustandsbezogenen Konzepten interagiert. Wenn Sie sich später dafür entscheiden, die Modalansicht in eine herkömmliche Ansicht umzuwandeln oder umgekehrt, muss nur sehr wenig Code geändert werden.

51
Nathan Williams

Hier ist eine provider, die die @ nathan-williams-Lösung verbessert, indem der resolve-Abschnitt an die controller übergeben wird:

.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;
}

dann benutze es so:

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

Ich habe eine ähnliche Frage beantwortet und hier ein Beispiel gegeben:

Modal-Fenster mit benutzerdefinierter URL in AngularJS

Hat einen vollständigen HTML-Code und einen Link zum Plunker.

2
cornernote

Das $ modal selbst hat keine close () - Funktion, ich meine, wenn Sie console.log ($ modal) verwenden, sehen Sie, dass es nur eine open () - Funktion gibt.

Das Schließen des Modals basiert auf dem $ modalInstance-Objekt, das Sie in Ihrem ModalController verwenden können.

Also: $ modal.close (Ergebnis) ist eigentlich keine Funktion!

Beachten : console.log ($ modal); == >> Ergebnis:

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

Es gibt einen Weg, dies zu lösen, eine Möglichkeit ist: 

Zuerst müssen Sie einen Controller in Ihrem Modal wie folgt definieren: 

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

Und dann später: 

    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