【问题标题】:Is it possible to clear the view cache in Ionic?是否可以清除 Ionic 中的视图缓存?
【发布时间】:2015-04-24 22:40:26
【问题描述】:

我目前正在处理一个 Angular/Ionic/Cordova 项目,我们最近升级到了最新的 Ionic 测试版。从项目之前使用的版本开始,这引入了视图缓存。然而,这样做也带来了一个问题。

该应用程序面向客户并且非常以数据为中心。然而,目前,用户必须进行身份验证才能查看与其帐户关联的数据;当用户注销并登录到另一个帐户时,因为视图仍被缓存,它们会显示最后一个帐户的视图。

当用户登录时,应用程序仍应缓存视图,因为它有助于使应用程序感觉更快,但应在用户注销时清除缓存。

设置cache-view="false" 不是一个选项,因为它会完全禁用缓存。

我也尝试过设置$ionicConfig.views.maxCache(0);,然后返回默认值10,希望这样做会清除缓存,但没有效果。

我能想到的最后一件事是在用户登录时触发一个事件,该事件会刷新当前加载到视图中的所有数据 - 但是,这会比我认为的需要更多的努力。

有没有办法简单地清除视图缓存?

【问题讨论】:

  • 我还想看到这个问题的答案,因为这种变化扰乱了我的工作流程。我发现 maxCache(0);方法只是禁用控制器的缓存(因此无论何时使用它们都会重新实例化它们)。在 Mac OSX 上,到目前为止,我在 Chrome 上解决此问题的方法是右键单击刷新按钮并选择“Emtpy Cache and Hard Reload”。

标签: javascript ionic


【解决方案1】:

你在寻找这样的东西吗?:

$ionicHistory.clearCache();

编辑:

Ionic 的 github 中有一个问题: Issue

【讨论】:

    【解决方案2】:

    在 app.js 的状态定义中,您可以添加 cache:false 以禁用缓存(请参阅 Ionic 文档中的 Disable cache within state provider。或者,您可以保持缓存,除非您知道数据已更改。

    • 如果您已经在页面上,您可以这样做,$state.go($state.currentState, {}, {reload:true})
    • 如果您处于另一个状态并且想要返回到通常缓存的状态但您希望它被刷新,您可以这样做,$ionicHistory.clearCache().then(function(){ $state.go('app.fooState') })

    注意,后者需要 clearCache 来返回一个承诺。查看我在此拉取请求中所做的更改,并将您现在拥有的 clearCache 实现与我的实现进行比较:https://github.com/driftyco/ionic/pull/3724

    【讨论】:

    • 太棒了。 “后一点”使我们“切换帐户”的用例变得非常简单。一行代码。非常感谢!
    • 注意:这里的“后一种”解决方案会清除所有视图除了当前处于活动状态的视图。如果您还想清除活动视图,一种解决方案是 1. 清除缓存,2. 导航到要刷新的页面,以及 3. 再次清除缓存。例如。 $ionicHistory.clearCache().then(function() { $state.go('app.fooState').then(function() { $ionicHistory.clearCache() } })
    • 如果你的 ionic clearCache 函数没有返回一个 promise,你总是可以像这样包装它:$q.when($ionicHistory.clearCache()).then(function(){ $state.go('app.fooState') })
    【解决方案3】:

    我偶然发现了一个类似的场景,在该场景中,使用其他用户登录时向我显示了陈旧/缓存的视图。您可以在状态定义级别执行cache: false,但这会完全禁用应用程序中该状态的缓存。

    当用户进入应用程序的登录/登录状态时(如您所说),您可以做的是清除所有缓存的视图和历史记录。看起来很理想。

    // code inside your signin controller
    
    $scope.$on("$ionicView.enter", function () {
       $ionicHistory.clearCache();
       $ionicHistory.clearHistory();
    });
    

    【讨论】:

    • 我偶然发现了一个退出后登录时总是显示白页的场景。您的解决方案轻松修复了这个功能齐全的交互式白屏。
    【解决方案4】:

    您也可以通过在您的$stateProvider 中设置cache:false 来做到这一点:

    $stateProvider.state('myState', {
       cache: false,
       url : '/myUrl',
       templateUrl : 'my-template.html'
    })
    

    【讨论】:

      【解决方案5】:

      这是一个老问题,我将解释实际发生的情况以及如何解决它:

      P.S:如果您想直接进入 SOLUTION,请立即向下滚动。

      $ionicHistory.clearCache()的代码:

       `clearCache: function(stateIds) { return $timeout(function() { 
           $ionicNavViewDelegate._instances.forEach(function(instance) { 
               instance.clearCache(stateIds); 
           }); 
       }`
      

      所以,如您所见,它需要 1 个参数,即 stateIds,它是一个 stateId 数组。事实上,我很难发现 stateId 只不过是 stateName。

      所以,让我们更深入。上面“instance.clearCache(stateIds)”行中使用的$ionicNavView.clearCache的代码是:

      self.clearCache = function(stateIds) {
      var viewElements = $element.children();
      var viewElement, viewScope, x, l, y, eleIdentifier;
      
      for (x = 0, l = viewElements.length; x < l; x++) {
        viewElement = viewElements.eq(x);
      
        if (stateIds) {
          eleIdentifier = viewElement.data(DATA_ELE_IDENTIFIER);
      
          for (y = 0; y < stateIds.length; y++) {
            if (eleIdentifier === stateIds[y]) {
              $ionicViewSwitcher.destroyViewEle(viewElement);
            }
          }
          continue;
        }
      
        if (navViewAttr(viewElement) == VIEW_STATUS_CACHED) {
          $ionicViewSwitcher.destroyViewEle(viewElement);
      
        } else if (navViewAttr(viewElement) == VIEW_STATUS_ACTIVE) {
          viewScope = viewElement.scope();
          viewScope && viewScope.$broadcast('$ionicView.clearCache');
        }
      
      }
      };
      

      正如您在代码中看到的,此 clearCache 不会清除所有缓存,相反,它会销毁与 stateIds 数组中的值匹配的所有缓存视图。如果没有参数,它只会破坏实际视图。

      因此,仅使用 Ionic 方式的解决方案是调用 $ionicHistory.clearCache() 并将数组中的所有状态名称作为参数。

      例如:解决方案 $ionicHistory.clearCache(['login', 'map', 'home']); 我不敢相信任何 Ionic 开发人员之前没有深入研究过代码,或者错过了这个简单的数据。有很多人为此而苦恼。

      为了清楚起见,我想指出错误本身的位置(如果我们可以称其为错误),也许对开发人员来说很方便:

      self.clearCache = function(stateIds){

      [...]

       var viewElements = $element.children();
      

      } 整个函数的作用基本上是:

      使用 JQLite 获取所有元素 循环元素 检查 StateIds 数组中的元素是否等于 1 并将其销毁;转到下一个元素。 检查循环中的元素是缓存还是活动的,在这两种情况下都销毁它 我不会对此进行深入研究,但调试它我可以看到元素来自 var viewElements = $element.children();不是所有视图内容的数组,甚至不是缓存的内容,有意或无意它不会遍历所有状态以清除所有与“活动”或“缓存”匹配的状态。如果您希望它遍历所有状态并销毁所有缓存的视图和数据,您需要显式传递 stateIds 数组参数。

      此外还有一个奇怪的行为,因为当我调试它时,我看到 var viewElements 数组被 2 个元素填充,而这 2 个元素来自相同的状态,一个解析为“缓存”另一个解析器为“ ACTIVE',甚至解析为 if 条件中使用的 2 种类型,缓存根本没有被清除。

      我个人认为这是某种错误的实现或被错误地广泛使用。事实是,有很多人对此感到困惑,而开发人员甚至没有给出这个简单的解释。

      【讨论】:

        猜你喜欢
        • 2021-10-16
        • 2016-12-05
        • 2011-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-19
        • 1970-01-01
        • 2016-05-30
        相关资源
        最近更新 更多