AngularJS - Angular UI-Router 只重新加载嵌套视图,而不是父视图 [英] AngularJS - Angular UI-Router reload only nested view, not parent

查看:26
本文介绍了AngularJS - Angular UI-Router 只重新加载嵌套视图,而不是父视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 $urlRouterProvider.otherwise("/projects/edit")$stateProvider.state('项目', {网址:/项目",模板:

"}).state('projects.edit', {解决: {测试:函数(){console.log('projects.edit 解析调用')}},网址:/编辑",templateUrl: "projects.html",控制器:函数($scope,$state){$state.go('projects.edit.surveys')$scope.transitionToOtherRoute = function () {$state.transitionTo('otherRoute')}}}).state('projects.edit.surveys', {解决: {项目:功能(){var randomNumberArray = [1,2,3,4,5,6]//这将只是洗牌数组for(var j, x, i = randomNumberArray.length; i; j = Math.floor(Math.random() * i), x = randomNumberArray[--i], randomNumberArray[i] = randomNumberArray[j], randomNumberArray[j] = x);返回随机数数组}},网址:/调查",意见:{视图A":{templateUrl: "projects.surveys.html",控制器:函数($scope,items,$state){$scope.items = 物品$scope.addSurvey = function(){$state.transitionTo($state.current, $state.params, { reload: true, inherit: true, notify: true })}}}}}).state('otherRoute', {url: "/otherRoute",templateUrl:"otherRoute.html"})

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

PROJECTS.HTML PARTIAL

<div class="row"><div class="col-md-6">输入文本:<input type="text"><br><button type="submit" class="btn btn-primary" ng-click="updateProject()">转到otherRoute</button>

<div class="col-md-6"><a ui-sref=".surveys"></a><div ui-view="viewA"></div>

用户将看到两列.左列将只有一个输入字段和按钮,按下后会将用户转换到 otherRoute 状态.

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

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

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

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

解决方案

有一个 plunker 有一个修改.我们可以从原生 ui-router 设计中获利,而不是使用非常极端的设置 reload: true:

<块引用>

重新加载状态,以防其声明的参数发生变化

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

.state('projects.edit.surveys', {解决: {...//不变},//这里我们声明参数触发器url: "/surveys/{trigger}",意见:{'' : {templateUrl: "projects.surveys.html",控制器:函数($scope,items,$state){$scope.items = 物品$scope.addSurvey = function(){//这里我们复制当前参数var params = angular.copy($state.params);//做一些不改变 URL 的技巧params.trigger = params.trigger === null ?": 空值;//进入相同状态但不重新加载:true$state.transitionTo($state.current, params, { reload: false, inherit: true, notify: true })}}}}})

从用户的角度来看,参数正在改变,但它的可见性没有变化 - 它是 null 或 string.Empty ... 检查调整和更原生的 ui-router 解决方案 这里

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:

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

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

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.

This can be seen in action in this 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.

Any help would be greatly appreciated!!!

解决方案

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

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

这篇关于AngularJS - Angular UI-Router 只重新加载嵌套视图,而不是父视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆