是否可以清除Ionic中的视图缓存?

时间:2015-02-23 14:59:49

标签: javascript ionic

我目前正在开展Angular / Ionic / Cordova项目,我们最近已升级到最新的Ionic beta版。从项目之前使用的版本开始,这引入了视图缓存。然而,它也引入了一个问题。

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

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

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

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

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

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

5 个答案:

答案 0 :(得分:65)

在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返回一个promise。查看我在此拉取请求中所做的更改,并将您现在拥有的clearCache的实现与我的实现进行比较:https://github.com/driftyco/ionic/pull/3724

答案 1 :(得分:19)

我偶然发现了一个类似的情况,其中登录其他用户向我展示陈旧/缓存的视图。您可以在州定义级别执行class Post < ActiveRecord::Base belongs_to :bread mount_uploader :attachment, AttachmentUploader end ,但这会完全禁用应用中该状态的缓存。

当用户输入应用程序的登录/登录状态时,您可以清除所有缓存的视图和历史记录(如您所述)。似乎很理想。

cache: false

答案 2 :(得分:8)

您也可以在cache:false

中设置$stateProvider来执行此操作
$stateProvider.state('myState', {
   cache: false,
   url : '/myUrl',
   templateUrl : 'my-template.html'
})

答案 3 :(得分:4)

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

$ionicHistory.clearCache();

编辑:

Ionic的github存在一个问题: Issue

答案 4 :(得分:0)

这是一个老问题,我将解释究竟发生了什么以及如何解决它:

P.S:如果你想直接进入解决方案,只需立即向下滚动。

$ ionicHistory.clearCache()的代码:

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

因此,正如您所看到的,它需要1个参数cllaed 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开发人员之前没有挖过代码,或者错过了这个简单的datail。有很多人为此感到痛苦。

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

self.clearCache = function(stateIds){

[...]

 var viewElements = $element.children();

} 整个功能的作用基本上是:

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

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

我个人认为这是某种错误的实施或被错误地广泛使用。事实是,有很多人对此表示不满,开发人员甚至没有给出这个简单的解释。