AngularJS - Angular UI-Router仅重新加载嵌套视图,而不是父视图

时间:2022-06-16 19:40:29

I know this is rather long, but I need to provide some context before my main question. I am creating a page that will be split into two columns. Here is the ui-router code:

我知道这很长,但我需要在我的主要问题之前提供一些背景知识。我正在创建一个将分为两列的页面。这是ui-router代码:

  $urlRouterProvider.otherwise("/projects/edit")

  $stateProvider
    .state('projects', {
      url: "/projects",
      template: "<div ui-view></div>"
    })

    .state('projects.edit', {
      resolve: {
        test: function(){
          console.log('projects.edit resolve called')
        }
      },
      url: "/edit",
      templateUrl: "projects.html",
      controller: function($scope, $state){
        $state.go('projects.edit.surveys')

        $scope.transitionToOtherRoute = function () {
            $state.transitionTo('otherRoute')
        }
      }
    })
    .state('projects.edit.surveys', {
      resolve: {
        items: function(){
          var randomNumberArray = [1,2,3,4,5,6]
          //this will just shuffle the array
          for(var j, x, i = randomNumberArray.length; i; j = Math.floor(Math.random() * i), x = randomNumberArray[--i], randomNumberArray[i] = randomNumberArray[j], randomNumberArray[j] = x);
          return randomNumberArray
        }
      },
      url: "/surveys",
      views: {
        "viewA": { 
            templateUrl: "projects.surveys.html",
            controller: function($scope, items, $state){
            $scope.items = items
            $scope.addSurvey = function(){
              $state.transitionTo($state.current, $state.params, { reload: true, inherit: true, notify: true })
            }
          }
        }
      }
    })
    .state('otherRoute', {
      url: "/otherRoute",
      templateUrl:"otherRoute.html"
    })

Basically, the user will be transitioned to the projects.edit state, which has a template that looks like this:

基本上,用户将转换到projects.edit状态,该状态具有如下所示的模板:

<h3>PROJECTS.HTML PARTIAL</h3>
<div class="row">
  <div class="col-md-6">
    Input Text: <input type="text"><br>
    <button type="submit" class="btn btn-primary" ng-click="updateProject()">Go to otherRoute</button>
  </div>
  <div class="col-md-6">
    <a ui-sref=".surveys"></a>
    <div ui-view="viewA"></div>
  </div>
</div>

The user will be presented with two columns. The left column will just have an input field and button, which when pressed will transition the user to the otherRoute state.

将向用户显示两列。左列只有一个输入字段和按钮,按下该按钮会将用户转换为otherRoute状态。

When we transition to the projects.edit state, it's controller will call $state.go('projects.edit.surveys'), which will set up it's nested view in the right column. The projects.edit.surveys state will first resolve an array of numbers in a random order, which it will pass into the controller as a parameter called items. The projects.surveys.html partial will then be placed in the right column. It will show the list of numbers in a random order and have a button, which calls $state.transitionTo($state.current, $state.params, { reload: true, inherit: true, notify: true }). This button will reload the projects.edit.surveys state. The user will see the numbers in a different order, and any text in the input field in the left column will disappear.

当我们转换到projects.edit状态时,它的控制器将调用$ state.go('projects.edit.surveys'),它将在右列中设置它的嵌套视图。 projects.edit.surveys状态将首先以随机顺序解析数字数组,它将作为名为items的参数传递给控制器​​。然后,projects.surveys.html partial将被放置在右栏中。它将以随机顺序显示数字列表,并有一个按钮,调用$ state.transitionTo($ state.current,$ state.params,{reload:true,inherit:true,notify:true})。此按钮将重新加载projects.edit.surveys状态。用户将以不同的顺序查看数字,左列中输入字段中的任何文本都将消失。

This can be seen in action in this Plunker: http://plnkr.co/edit/SK8hjMpw6kvPiTdVeEhz?p=preview

这可以在这个Plunker中看到:http://plnkr.co/edit/SK8hjMpw6kvPiTdVeEhz?p=preview

This all leads to my question: how can I only reload the content of the right column ie the nested view (projects.edit.surveys), without reloading the parent view (projects.edit)? I would like to be able press the button in the right column and only re-sort the numbers, which is done in projects.edit.surveys state's resolve, and not clear the input field in the left column (and not call the resolve methods in projects.edit). In other words, I'd like only refresh the right column projects.edit.surveys state, without affecting anything in the left hand projects.edit state.

这一切都引出了我的问题:我怎样才能重新加载右列的内容,即嵌套视图(projects.edit.surveys),而无需重新加载父视图(projects.edit)?我希望能够按下右栏中的按钮,只重新排序数字,这是在projects.edit.surveys状态的解析中完成的,而不是清除左栏中的输入字段(而不是调用解析方法)在projects.edit)。换句话说,我只想刷新右列projects.edit.surveys状态,而不影响左手projects.edit状态中的任何内容。

Any help would be greatly appreciated!!!

任何帮助将不胜感激!!!

1 个解决方案

#1


7  

There is a plunker with one modification. Instead of using very extreme setting reload: true, we can profit from native ui-router desing:

有一个带有一个修改的plunker。而不是使用非常极端的设置重载:true,我们可以从本机ui-router设计中获利:

reload the state in case its declared param has changed

如果声明的参数已更改,则重新加载状态

So, this would be the new state and controller definition:

所以,这将是新的状态和控制器定义:

.state('projects.edit.surveys', {
      resolve: {
        ... // unchanged
      },
      // here we declare param trigger
      url: "/surveys/{trigger}",
      views: { 
      '' : { 
            templateUrl: "projects.surveys.html",
            controller: function($scope, items, $state){
              $scope.items = items
              $scope.addSurvey = function(){

                // here we copy current params
                var params = angular.copy($state.params);
                // do some tricks to not change URL
                params.trigger = params.trigger === null ? "" : null;
                // go to the same state but without reload : true
                $state.transitionTo($state.current, params, { reload: false, inherit: true, notify: true })
              }
            }
        }
      }
    })

From a user perspective, param is changing but not its visibility - it is null or string.Empty ... Check that adjustment and a bit more native ui-router solution here

从用户的角度来看,param正在改变但不是它的可见性 - 它是null或string.Empty ...在这里检查调整和更多的本机ui-router解决方案

#1


7  

There is a plunker with one modification. Instead of using very extreme setting reload: true, we can profit from native ui-router desing:

有一个带有一个修改的plunker。而不是使用非常极端的设置重载:true,我们可以从本机ui-router设计中获利:

reload the state in case its declared param has changed

如果声明的参数已更改,则重新加载状态

So, this would be the new state and controller definition:

所以,这将是新的状态和控制器定义:

.state('projects.edit.surveys', {
      resolve: {
        ... // unchanged
      },
      // here we declare param trigger
      url: "/surveys/{trigger}",
      views: { 
      '' : { 
            templateUrl: "projects.surveys.html",
            controller: function($scope, items, $state){
              $scope.items = items
              $scope.addSurvey = function(){

                // here we copy current params
                var params = angular.copy($state.params);
                // do some tricks to not change URL
                params.trigger = params.trigger === null ? "" : null;
                // go to the same state but without reload : true
                $state.transitionTo($state.current, params, { reload: false, inherit: true, notify: true })
              }
            }
        }
      }
    })

From a user perspective, param is changing but not its visibility - it is null or string.Empty ... Check that adjustment and a bit more native ui-router solution here

从用户的角度来看,param正在改变但不是它的可见性 - 它是null或string.Empty ...在这里检查调整和更多的本机ui-router解决方案