【问题标题】:Angular ui-router shows old stale data after transition back to stateAngular ui-router 在转换回状态后显示旧的陈旧数据
【发布时间】:2016-06-26 03:26:59
【问题描述】:

我们有一个使用 ui-router AngularJS 模块的 ASP.NET MVC 5 应用程序。

当我们回到已经加载的状态时,它总是显示旧数据,直到我们进行整页刷新。

例如:

  • 用户点击“查看个人资料”,我们显示“查看个人资料”状态,显示个人资料的页面
  • 用户点击“编辑配置文件”,我们显示“编辑配置文件”状态,一个包含编辑配置文件字段的页面
  • 用户进行更改并单击“保存”,然后将其移回“查看配置文件”状态
  • “ViewProfile”状态加载时,仍会显示编辑前的旧数据

我们如何强制 ui-route 在加载任何状态时提取新数据?

角度配置

var app = angular.module("MyApp", ['ngIdle', 'ui.router'])
    .config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
        function ($stateProvider, $urlRouterProvider, $locationProvider) {
            // Configure client-side routing
            $locationProvider.hashPrefix("!").html5Mode(true);
            $urlRouterProvider.otherwise("/");

            $stateProvider
                .state('Home', {
                    url: '/',
                    views: {
                        "mainContainer": {
                            templateUrl: function (params) { return 'Home/Index'; }
                        }
                    }
                })                    
                .state('ProfileManagement', {
                    url: '/ProfileManagement-{action}',
                    views: {
                        "mainContainer": {
                            templateUrl: function (params) { return 'ProfileManagement/' + params.action; }
                        }
                    }
                })
        }]);

我们是如何进行过渡的

$state.go(stateName, { action: actionName }, { reload: true, inherit: false, notify: true });

使用解决方案编辑 由于所有功能都是使用 jQuery 编写的,因此我们不能使用 Angular 控制器来控制数据。我们的解决方案是使用以下代码完全禁用 Angular 模板缓存:

app.run(function ($rootScope, $templateCache) {
        $rootScope.$on('$viewContentLoaded', function () {
            $templateCache.removeAll();
        });
    });

【问题讨论】:

  • 老问题,但有同样的问题。我添加了您的代码,但这次我丢失了所有全局信息。有什么想法吗?

标签: angularjs asp.net-mvc angular-ui-router angularjs-routing


【解决方案1】:

默认情况下 ui-router 状态转换不会重新实例化 toState 的控制器。

要强制实例化控制器,您可以这样做。

//assuming you are using $state.go to go back to previous state
$state.go('to.state', params, {
   reload: true
});

【讨论】:

  • 感谢您的回复。这就是我们进行过渡的方式,但它似乎不起作用。我已编辑问题以显示我们如何执行转换。
  • 你能分享 ViewProfile 状态的控制器代码吗?
  • 此状态没有特定的控制器。这个应用程序使用 jQuery 来实现所有功能,并且只使用 Angular 来实现路由。基本上,在成功发布表单后,我们调用一个 JS 函数来获取范围并调用范围控制器上调用 $state.go 的方法。我知道这不是理想的设置,但在我们实施角度路由之前,所有功能都已经到位。
【解决方案2】:

你需要使用解析,像这样:

var app = angular.module("MyApp", ['ngIdle', 'ui.router'])
  .config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
    function ($stateProvider, $urlRouterProvider, $locationProvider) {
      // Configure client-side routing
      $locationProvider.hashPrefix("!").html5Mode(true);
      $urlRouterProvider.otherwise("/");

      $stateProvider
        .state('Home', {
          url: '/',
          views: {
            "mainContainer": {
              templateUrl: function (params) { return 'Home/Index'; }
            }
          },
          resolve: {
            loadedData: (injectable) => injectable.getData()
          }
        })                    
        .state('ProfileManagement', {
          url: '/ProfileManagement-{action}',
          views: {
            "mainContainer": {
              templateUrl: function (params) { return 'ProfileManagement/' + params.action; }
            }
          },
          resolve: {
            loadedData: (injectable) => injectable.getData()
          }
        })
    }]);

在每个状态中,都有一个解析,在可注入服务中调用方法“getData()”(我说的是“服务”,因为我们将从那里加载数据)。

那么对于每个状态的控制器,它都可以访问到loadedData解析;数据将在该点加载并可供该控制器使用。因此,对于您的案例场景,回到您来自的状态,新更新的数据将再次加载并再次在该状态下可用。

使用 reload: true 保持您的状态转换不变,因为这也是您想要的。

【讨论】:

  • 即使状态没有定义特定的控制器,这也能工作吗?我尝试在我的状态定义中添加这个“解析”属性,但它不允许加载状态。
  • 您可能需要为每个州配备一个控制器,是的。这样您就可以从解析的返回中提取数据,以在模板中使用。
  • 知道了。不幸的是,我们没有那么奢侈,因为所有这些功能都已经用 jQuery 编写了 :( 。我们通过在全局级别禁用模板缓存来解决这个问题(请参阅更新的问题)。感谢您的帮助。
【解决方案3】:

也许这对你的问题有用。

在您的 Angular 主页中,您应该有这样的内容:

app.run(['$rootScope', function ($rootScope){ $rootScope.$on('$stateChangeStart', function(event, toState){ $rootScope.UrlActive=toState.name; }); }]);

在你的角度控制器中你应该有这样的东西:

app.controller('AnalisisCtrl', ['$scope','$rootScope', function ($scope,$rootScope) { $scope.$watch('UrlActive', function(newValue) { if(newValue="ProfileManagement"){ doSomething(); }; }); }]);

【讨论】:

    猜你喜欢
    • 2019-11-08
    • 2019-01-24
    • 1970-01-01
    • 2015-08-30
    • 2016-08-06
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    相关资源
    最近更新 更多