我正在开发我的第一款带有离子和AngularJS的混合移动应用程序,而这正是我想弄清楚的一件事:我们如何保持导航之间的状态(如GUI)?假设我的应用程序有一个包含这些项目链接的侧边菜单:
#/all
)#/cats
)#/dogs
)#/cows
)#/contact
)2到5的项目以inifite加载方式触发请求服务器数据。
现在让我们说从 Cats ,我去 Dogs ,然后回到 Cats 。由于(根据我的理解),每次路由更改都会创建一个全新的Controller实例(和范围),应用程序将从服务器重新加载猫的列表。我希望保留 Cats 状态,然后重新显示。
我一直在寻找一个解决方案(我认为应该足够普遍,只是我没有使用正确的搜索条件)。到目前为止,我发现的所有结果都建议您监听state change
或route change
种事件,并将对象数组存储到localStorage
中。虽然,对于某些扩展,这项工作,我觉得它是笨拙的,而不是做的方式 - 例如,HTML必须编译,这可能非常慢(注意我前面提到的“无限加载”功能,可以将对象数量增加到数百个,并且视口将恢复到应用程序的顶部。
所以我的问题是,你们如何处理这个问题?是否有任何类似于浏览器后退和前进按钮的导航?
答案 0 :(得分:1)
如果我理解你想要什么,你需要使用AngularJS服务。有关解释的详细信息,请参阅Ionic文档中的这篇文章:
http://learn.ionicframework.com/formulas/sharing-data-between-views/
在“与服务共享数据”部分中,您的问题的答案就在那里。
答案 1 :(得分:0)
我遇到了相反的问题,如果用户回到同一页面我想要刷新,但它不是。在过去10个月的某个时刻(在我提出这个问题和我写这篇文章之间),我相信Ionic实现了一个页面缓存,使他们的iOS幻灯片返回效果起作用。所以你的问题可能已经解决了,但以防万一...
通过添加" cache:false"修复了我的问题。到模块的.config()部分中的每个状态的选项。但是,在某些页面(或状态,我猜)我不希望它们重新加载,但是当用户回到它时我无法确定页面/状态是否仍然在缓存中。所以我决定在$ rootScope中设置一个标志...或者更确切地说,在$ rootScope中设置一个包含每个控制器的标志变量的对象,然后检查标志以查看该页面是否已被加载,并且如果是这样,请不要运行任何控制器代码。因此,对于您描述的设置,您将拥有以下内容:
angular.module('MyApp', ['ionic'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('Search' , { cache: true , url:'/Search' , templateUrl:'templates/Search.html' , controller: 'SearchController' })
.state('All' , { cache: true , url:'/All' , templateUrl:'templates/All.html' , controller: 'AllController' })
.state('Dogs' , { cache: true , url:'/Dogs' , templateUrl:'templates/Dogs.html' , controller: 'CatsController' })
.state('Cows' , { cache: true , url:'/Cows' , templateUrl:'templates/Cows.html' , controller: 'DogsController' })
.state('Cats' , { cache: true , url:'/Cats' , templateUrl:'templates/Cats.html' , controller: 'CowsController' })
.state('Contact' , { cache: true , url:'/Contact' , templateUrl:'templates/Contact.html' , controller: 'ContactController' });
$urlRouterProvider.otherwise('/');
});
然后对于控制器,您可以这样做:
.controller('SearchController', function($scope, $rootScope, $state) {
// If $rootScope.flags does not already exist, create it as an empty object
$rootScope.flags = $rootScope.flags || {};
if($rootScope.flags.SearchPageHasBeenOpenedAlready) {
console.log("Search page was already opened, not doing anything.");
return;
} else {
// Assuming this is the first controller, I guess you could initialize the flags here...
// We will initialize them all to false and not set them to true until the code for
// each controller has run through successfully
$rootScope.flags.SearchPageHasBeenOpenedAlready = false;
$rootScope.flags.AllPageHasBeenOpenedAlready = false;
$rootScope.flags.CatsPageHasBeenOpenedAlready = false;
$rootScope.flags.DogsPageHasBeenOpenedAlready = false;
$rootScope.flags.CowsPageHasBeenOpenedAlready = false;
$rootScope.flags.ContactPageHasBeenOpenedAlready = false;
}
/* Whatever you normally do in SearchController goes here */
$rootScope.flags.SearchPageHasBeenOpenedAlready = true;
}
)
.controller('AllController', function($scope, $rootScope, $state) {
// If $rootScope.flags does not already exist, create it as an empty object
$rootScope.flags = $rootScope.flags || {};
if($rootScope.flags.AllPageHasBeenOpenedAlready) {
console.log("All page was already opened, not doing anything.");
return;
}
/* Whatever you normally do in AllController goes here */
$rootScope.flags.AllPageHasBeenOpenedAlready = true;
}
)
/*
And so forth until the last one...
*/
.controller('ContactController', function($scope, $rootScope, $state) {
// If $rootScope.flags does not already exist, create it as an empty object
$rootScope.flags = $rootScope.flags || {};
if($rootScope.flags.ContactPageHasBeenOpenedAlready) {
console.log("Contact page was already opened, not doing anything.");
return;
}
/* Whatever you normally do in ContactController goes here */
$rootScope.flags.ContactPageHasBeenOpenedAlready = true;
}
);