Usando ui-router con Bootstrap-ui modal

So che questo è stato trattato molte volte e la maggior parte degli articoli fa riferimento a questo bit di codice: finestra modale con URL personalizzato in AngularJS

Ma proprio non capisco. Non lo trovo molto chiaro. Ho anche trovato questo jsfiddle che in realtà è stato fantastico, molto utile, tranne che non aggiunge l’url e mi consente di usare il pulsante Indietro per chiudere il modal.


Modifica: questo è quello che ho bisogno di aiuto con.

Quindi lascia che provi a spiegare cosa sto cercando di ottenere. Ho un modulo per aggiungere un nuovo elemento e ho un link ‘aggiungi un nuovo elemento’. Vorrei che quando faccio clic su “aggiungi un nuovo elemento” venga visualizzata una modale con il modulo che ho creato “add-item.html”. Questo è un nuovo stato quindi l’URL cambia in / add-item. Posso compilare il modulo e poi scegliere di salvare o chiudere. Chiudi, chiude il modale: p (che strano). Ma posso anche cliccare di nuovo per chiudere il modale e tornare alla pagina precedente (stato). Non ho bisogno di aiuto con Close in questo momento perché sto ancora cercando di ottenere effettivamente il funzionamento modale.


Questo è il mio codice così com’è:

Controller di navigazione: (è questo anche il posto giusto in cui inserire le funzioni modali?)

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

Ecco come sto triggersndo il modale:

  
  • New Item
  • new-item.html:

        

    Anche se questo apre un modale, non lo chiude perché non potrei farlo.

    È intuitivo pensare a una modale come componente di visualizzazione di uno stato. Prendi una definizione di stato con un modello di visualizzazione, un controller e forse alcune risoluzioni. Ognuna di queste caratteristiche si applica anche alla definizione di una modale. Fai un passo avanti e collega la voce dello stato all’apertura dell’uscita modale e dello stato alla chiusura della modale, e se riesci a incapsulare tutto l’impianto idraulico, allora hai un meccanismo che può essere usato come uno stato con ui-sref o $state.go per la voce e il pulsante indietro o più trigger modali specifici per l’uscita.

    Ho studiato questo abbastanza ampiamente , e il mio approccio è stato quello di creare un provider di stato modale che potrebbe essere utilizzato in modo analogo a $stateProvider quando si configura un modulo per definire stati che erano legati a modali. All’epoca, ero specificamente interessato a unificare il controllo sul licenziamento modale attraverso eventi statali e modali che diventa più complicato di quello che stai chiedendo, quindi ecco un esempio semplificato .

    La chiave sta rendendo il modale la responsabilità dello stato e l’utilizzo di hook che modale fornisce per mantenere lo stato in sincrono con interazioni indipendenti supportate dal modale attraverso l’ambito o la sua interfaccia utente.

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

    La voce di stato avvia il modale. L’uscita di stato lo chiude. La modale potrebbe chiudersi da sola (es: tramite clic sullo sfondo), quindi devi osservarlo e aggiornare lo stato.

    Il vantaggio di questo approccio è che la tua app continua a interagire principalmente con gli stati e i concetti relativi allo stato. Se in un secondo momento decidi di trasformare la modale in una vista convenzionale o viceversa, allora il codice molto piccolo deve essere modificato.

    Ecco un provider che migliora la soluzione di @ nathan-williams resolve sezione di resolve al 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; } 

    quindi usarlo in questo modo:

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

    Ho risposto a una domanda simile e ho fornito un esempio qui:

    Finestra modale con URL personalizzato in AngularJS

    Ha un codice HTML completo funzionante e un collegamento a plunker.

    Il $ modal stesso non ha una funzione di chiusura (), voglio dire Se tu console.log ($ modal), puoi vedere che c’è solo una funzione open ().

    La chiusura del modale si basa sull’object $ modalInstance, che puoi usare nel tuo modalController.

    Quindi questo: $ modal.close (risultato) non è in realtà una funzione!

    Avviso: console.log ($ modal); == >> risultato:

      Object { open: a.$get 

    C'è un modo per risolvere questo, un modo è:

    Per prima cosa devi definire un controller nel tuo modal come questo:

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

    E poi, in seguito,:

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