Using ui-router with Bootstrap-ui modal

后端 未结 4 1407
暗喜
暗喜 2020-11-28 21:22

I know this has been covered many times and most articles refer to this bit of code: Modal window with custom URL in AngularJS

But I just don\'t get it. I don\'t fin

相关标签:
4条回答
  • 2020-11-28 21:31

    I answered a similar question, and provided an example here:

    Modal window with custom URL in AngularJS

    Has a complete working HTML and a link to plunker.

    0 讨论(0)
  • 2020-11-28 21:34

    It's intuitive to think of a modal as the view component of a state. Take a state definition with a view template, a controller and maybe some resolves. Each of those features also applies to the definition of a modal. Go a step further and link state entry to opening the modal and state exit to closing the modal, and if you can encapsulate all of the plumbing then you have a mechanism that can be used just like a state with ui-sref or $state.go for entry and the back button or more modal-specific triggers for exit.

    I've studied this fairly extensively, and my approach was to create a modal state provider that could be used analogously to $stateProvider when configuring a module to define states that were bound to modals. At the time, I was specifically interested in unifying control over modal dismissal through state and modal events which gets more complicated than what you're asking for, so here is a simplified example.

    The key is making the modal the responsibility of the state and using hooks that modal provides to keep the state in sync with independent interactions that modal supports through the scope or its UI.

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

    State entry launches the modal. State exit closes it. The modal might close on its own (ex: via backdrop click), so you have to observe that and update the state.

    The benefit of this approach is that your app continues to interact mainly with states and state-related concepts. If you later decide to turn the modal into a conventional view or vice-versa, then very little code needs to change.

    0 讨论(0)
  • 2020-11-28 21:57

    The $modal itself doesn't have a close() funcftion , I mean If you console.log($modal) , You can see that there is just an open() function.

    Closing the modal relies on $modalInstance object , that you can use in your modalController.

    So This : $modal.close(result) is not actually a function!

    Notice : console.log($modal); ==>> result :

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

    There is some way to solve this , one way is :

    First you must define a controller in your modal like this :

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

    And then , Later on , :

        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 讨论(0)
  • 2020-11-28 21:58

    Here is a provider that improves @nathan-williams solution by passing resolve section down to the 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;
    }
    

    then use it like that:

    .config(['modalStateProvider', function(modalStateProvider) {
      modalStateProvider
        .state('...', {
          url: '...',
          templateUrl: '...',
          controller: '...',
          resolve: {
            ...
          }
        })
    }]);
    
    0 讨论(0)
提交回复
热议问题