【问题标题】:How to maintain view (controller) state between route changes?如何在路由更改之间维护视图(控制器)状态?
【发布时间】:2014-12-09 21:34:14
【问题描述】:

我有一个用 AngularJS 编写并使用 ui-router 管理状态转换(路由)的单页应用程序。

有一个搜索状态是这样配置的:

function config($stateProvider) {
  $stateProvider
    .state('social.search', {
      url: '/search',
      templateUrl: 'views/social/search/social-search-view.html',
      controller: 'SocialSearchController',
      controllerAs: 'vm'
    });
}

此视图呈现一个表单,控制器 (SocialSearchController) 负责获取这些输入,将它们提交给服务并显示结果。结果列表以排名列表的形式显示给用户(如 Google 的搜索结果页面)。每个结果都有一个链接可以转到新状态以显示有关条目的详细信息,例如:

<a ui-sref="social.profile({personId: person.id})">{{person.name}}</a>

social.profile状态用于应用程序的其他部分,所以它不是social.search的子状态,它是这样配置的:

function config($stateProvider) {
  $stateProvider.state('social.profile', {
    url: '/{personId}',
    templateUrl: 'views/social/profile/social-profile-view.html',
    controller: 'SocialProfileController',
    controllerAs: 'vm'
  });
}

它工作正常,我可以输入我的搜索,获取结果,然后单击以查看有关条目的详细信息。但是,当我点击返回按钮从详细视图转换回搜索视图时,我的输入和搜索结果都消失了。我知道这是默认且正确的行为,因为如果不再使用控制器,则无需将其保留在内存中。

问题是,在这个特定场景中,我希望控制器以某种方式留在内存中,因此用户不需要重新输入查询并发出另一个搜索服务请求。

我可以考虑将搜索状态保存到服务中,并让控制器从中获取其初始状态,类似于缓存服务,用于存储最后一个控制器的状态。但是我很容易受到这个同步过程中涉及的错误的影响,搜索表单有点复杂,因为它涉及自动完成和标签字段(我已经制作的自定义指令),所以同步将通过至少三个“层” :控制器状态、缓存服务、自定义输入。

这是正确的方法吗?我有哪些选择?

【问题讨论】:

  • 如何为您的搜索结果添加另一个视图 ('/search/{searchString}')。您的表单将“提交”到该视图,并且 profiel 视图中的后退按钮将起作用。
  • 我有比单个搜索字符串更多的字段,但我明白你的意思(保持路由 url 中的输入状态)。这将有助于用户避免重新输入,但它会向搜索服务(后端)发出新请求以重新填充结果列表。
  • 我认为如果它再次发出请求是正确的,(例如,您可能有新的结果要显示),但这可能取决于您的要求。

标签: javascript angularjs angular-ui-router


【解决方案1】:

我不确定 ui-router 是否将控制器和数据保存在父状态和子状态之间,但如果是这种情况,您可以尝试“复制”您的状态。

function config($stateProvider) {

 var socialProfile = {
    url: '/{personId}',
    templateUrl: 'views/social/profile/social-profile-view.html',
    controller: 'SocialProfileController',
    controllerAs: 'vm' } 

  $stateProvider
    .state('social.search', {
      url: '/search',
      templateUrl: 'views/social/search/social-search-view.html',
      controller: 'SocialSearchController',
      controllerAs: 'vm'
    });
    $stateProvider.state("social.search.detail', socialProfile);
    $stateProvider.state('social.profile', socialProfile);  
  }

在“social.search”视图中,您可以只拥有一个特殊的 href

<a ui-sref="social.search.detail({personId: person.id})">{{person.name}}</a>

在此配置中,您的 socialProfile 是搜索的子状态,但也保持独立状态

【讨论】:

  • 这似乎可行,但我需要在父状态中添加ui-view 以显示详细视图。就我而言,我希望这个孩子ui-view 占据整个视图。有什么办法可以通过ng-if 或类似的方式检查是否存在子状态?
猜你喜欢
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-29
  • 2010-11-29
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
相关资源
最近更新 更多