feat(clearCache): create $ionicHistory.clearCache()

This commit is contained in:
Adam Bradley
2014-11-21 17:09:53 -06:00
parent 5a28bbb1bd
commit 2683ffd075
5 changed files with 106 additions and 13 deletions

View File

@@ -6,9 +6,10 @@ IonicModule
'$compile',
'$controller',
'$ionicNavBarDelegate',
'$ionicNavViewDelegate',
'$ionicHistory',
'$ionicViewSwitcher',
function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate, $ionicHistory, $ionicViewSwitcher) {
function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate, $ionicNavViewDelegate, $ionicHistory, $ionicViewSwitcher) {
var DATA_ELE_IDENTIFIER = '$eleId';
var VIEW_STATUS_ACTIVE = 'active';
@@ -36,6 +37,9 @@ function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate,
var viewData = { name: navViewName, state: null };
$element.data('$uiView', viewData);
var deregisterInstance = $ionicNavViewDelegate._registerInstance(self, $attrs.delegateHandle);
$scope.$on('$destroy', deregisterInstance);
return viewData;
};
@@ -154,6 +158,18 @@ function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate,
};
self.clearCache = function() {
var viewElements = $element.children();
for (var x = 0, l = viewElements.length; x < l; x++) {
if (navViewAttr(viewElements.eq(x)) == VIEW_STATUS_CACHED) {
$ionicViewSwitcher.destroyViewEle(viewElements.eq(x));
}
}
};
self.getViewElements = function() {
return $element.children();
};

View File

@@ -22,7 +22,8 @@ IonicModule
'$location',
'$window',
'$ionicViewSwitcher',
function($rootScope, $state, $location, $window, $ionicViewSwitcher) {
'$ionicNavViewDelegate',
function($rootScope, $state, $location, $window, $ionicViewSwitcher, $ionicNavViewDelegate) {
// history actions while navigating views
var ACTION_INITIAL_VIEW = 'initialView';
@@ -586,6 +587,18 @@ function($rootScope, $state, $location, $window, $ionicViewSwitcher) {
}
},
/**
* @ngdoc method
* @name $ionicHistory#clearCache
* @description Removes all cached views within every {@link ionic.directive:ionNavView}.
* This both removes the view element from the DOM, and destroy it's scope.
*/
clearCache: function() {
$ionicNavViewDelegate._instances.forEach(function(instance) {
instance.clearCache();
});
},
/**
* @ngdoc method
* @name $ionicHistory#nextViewOptions

6
js/angular/service/navViewDelegate.js vendored Normal file
View File

@@ -0,0 +1,6 @@
IonicModule
.service('$ionicNavViewDelegate', delegateService([
'clearCache'
]));

View File

@@ -90,7 +90,7 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
function destroyViewEle(ele) {
// we found an element that should be removed
// destroy its scope, then remove the element
if (ele) {
if (ele && ele.length) {
var viewScope = ele.scope();
viewScope && viewScope.$destroy();
ele.remove();
@@ -253,9 +253,9 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
// 7) start the transition
viewTransition.run(1);
for (var x = 0; x < $ionicNavBarDelegate._instances.length; x++) {
$ionicNavBarDelegate._instances[x].triggerTransitionStart(transitionId);
}
$ionicNavBarDelegate._instances.forEach(function(instance) {
instance.triggerTransitionStart(transitionId);
});
if (!viewTransition.shouldAnimate) {
// no animated transition
@@ -285,9 +285,9 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
switcher.cleanup(enteringData);
}
for (var x = 0; x < $ionicNavBarDelegate._instances.length; x++) {
$ionicNavBarDelegate._instances[x].triggerTransitionEnd();
}
$ionicNavBarDelegate._instances.forEach(function(instance) {
instance.triggerTransitionEnd();
});
// remove any references that could cause memory issues
nextTransition = nextDirection = enteringView = leavingView = enteringEle = leavingEle = null;
@@ -338,7 +338,7 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
oldestAccess = viewElement.data(DATA_VIEW_ACCESSED);
removableEle = viewElements.eq(x);
} else if (viewElement.data(DATA_DESTROY_ELE) && cachedAttr(viewElement) != VIEW_STATUS_ACTIVE) {
} else if (viewElement.data(DATA_DESTROY_ELE) && navViewAttr(viewElement) != VIEW_STATUS_ACTIVE) {
destroyViewEle(viewElement);
}
}
@@ -415,6 +415,7 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
getTransitionData: getTransitionData,
historyCursorAttr: historyCursorAttr,
navViewAttr: navViewAttr,
destroyViewEle: destroyViewEle
};

View File

@@ -2,7 +2,7 @@
describe('Ionic nav-view', function() {
beforeEach(module('ionic'));
var compile, viewService, $rootScope, elem;
var compile, $rootScope, elem;
var aState = {
template: 'aState template'
@@ -131,8 +131,7 @@ describe('Ionic nav-view', function() {
.state('ionViewCacheFalseProperty', ionViewCacheFalsePropertyState);
}));
beforeEach(inject(function(_$compile_, $ionicHistory, $ionicConfig, $rootScope) {
viewService = $ionicHistory;
beforeEach(inject(function(_$compile_, $ionicConfig, $rootScope) {
$compile = _$compile_;
scope = $rootScope.$new();
elem = angular.element('<div>');
@@ -816,6 +815,64 @@ describe('Ionic nav-view', function() {
expect(leave.transitionId).toEqual(4);
}));
it('should clear ion-nav-view cache', inject(function ($state, $q, $timeout, $compile, $ionicHistory) {
elem.append($compile('<div><ion-nav-view></ion-nav-view></div>')(scope));
$state.go(page1State);
$q.flush();
$timeout.flush();
$timeout.flush();
$state.go(page2State);
$q.flush();
$timeout.flush();
$timeout.flush();
$state.go(page3State);
$q.flush();
$timeout.flush();
$timeout.flush();
var divs = elem.find('ion-nav-view').find('div');
expect(divs.length).toBe(3);
expect(divs.eq(0).attr('nav-view')).toBe('cached');
expect(divs.eq(0).text()).toBe('page1');
expect(divs.eq(1).attr('nav-view')).toBe('cached');
expect(divs.eq(1).text()).toBe('page2');
expect(divs.eq(2).attr('nav-view')).toBe('active');
expect(divs.eq(2).text()).toBe('page3');
$ionicHistory.clearCache();
var divs = elem.find('ion-nav-view').find('div');
expect(divs.length).toBe(1);
expect(divs.eq(0).attr('nav-view')).toBe('active');
expect(divs.eq(0).text()).toBe('page3');
$ionicHistory.clearCache();
var divs = elem.find('ion-nav-view').find('div');
expect(divs.length).toBe(1);
expect(divs.eq(0).attr('nav-view')).toBe('active');
expect(divs.eq(0).text()).toBe('page3');
$state.go(page2State);
$q.flush();
$timeout.flush();
$timeout.flush();
var divs = elem.find('ion-nav-view').find('div');
expect(divs.length).toBe(1);
expect(divs.eq(0).attr('nav-view')).toBe('active');
expect(divs.eq(0).text()).toBe('page2');
}));
});
angular.module('ngMock').config(function ($provide) {