Ion-list is not updated after calling $ state.go

I am studying AngularJS and ionic structure using this tutorial:

http://www.htmlxprs.com/post/12/tutorial-on-using-parse-rest-api-and-ionic-framework-together

Everything works well until the moment when I create a new element in createTodo state and then call $ state.go ('todos') to return to the list of my elements, here is the code for creating Todo Controller:

.controller('TodoCreateController', ['$scope', 'Todo', '$state', function($scope, Todo, $state) { $scope.todo = {}; $scope.create = function() { Todo.create({content: $scope.todo.content}).success(function(data) { $state.go('todos', {}, {reload: true}); }); } }]) 

Here is the code for the item list controller:

 .controller('TodoListController', ['$scope', 'Todo', '$state', function($scope, Todo) { Todo.getAll().success(function(data) { $scope.items = data.results; }); $scope.deleteItem = function(item) { Todo.delete(item.objectId); $scope.items.splice($scope.items.indexOf(item), 1); }; }]) 

The states are configured here.

 .config(function($stateProvider) { $stateProvider.state('todos', { url: '/todos', controller: 'TodoListController', templateUrl: 'views/todos.html' }).state('createTodo', { url: '/todo/new', controller: 'TodoCreateController', templateUrl: 'views/create-todo.html' }); }) 

When the application starts, the TodoListController method is called thanks to the last line added and the end of the .run method in the main app.js (or at least this is my understanding):

 .run(function($ionicPlatform, $state) { $ionicPlatform.ready(function() { if(window.cordova && window.cordova.plugins.Keyboard) { cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); } if(window.StatusBar) { StatusBar.styleDefault(); } }); $state.go('todos'); }) 

My problem is that as soon as a new element is created and I call $ state.go ('todos') from TodoCreateController, it returns me to the list of elements, but the new element is not there, and the method from TodoListController is never called, therefore leaving the list obsolete.

How to update the list in the "todos" state after creating a new item?

+6
source share
4 answers

I found a pretty elegant solution:

Inside my TodoListController, I define an event listener as follows:

 $rootScope.$on('todo:listChanged', function() { $scope.updateList(); }); 

then the updateList () method appears

 $scope.updateList = function() { Todo.getAll().success(function(data) { $scope.items = data.results; }); }; 

And finally, in TodoCreateController, I $ throws an event up as soon as the element is created, and right before the state change

 $scope.create = function() { Todo.create({content: $scope.todo.content}).success(function(data) { $scope.$emit('todo:listChanged'); $state.go('todos'); }); }; 

And voila! The list is updated accordingly, and now I can use the same event if I delete or update the list item

+12
source

I ran into this and similar problems, and it turned out that caching the ionic representation was often the reason for the failure when calling the controller code when returning to the cached view.

Possible Solution

When dividing the controller code into one-time initialization and code execution when presenting the view, controllers usually end up looking like this:

 // one-time initialization $scope.updateList = function() { Todo.getAll().success(function(data) { $scope.items = data.results; }); }; $scope.$on('$ionicView.beforeEnter', function () { $scope.updateList(); }); 

This should solve your problem without having to trigger events or add parameters or data to the route.

Alternative

You can disable image caching in different ways:

  • add cache: false to state definition
  • add cache-view="false" to html <ion-view ...>
  • disable caching with $ionicConfigProvider.views.maxCache(0); (Not recommended)

Pitfall when using sub-states

Not in your case, but if you edit / create lines in Sub-states (for example, todo specified for the list and todo.create for creating a new todo), an additional problem arises from ui-router:

When you switch from todo.create to todo your todo super-state will fail because you are already in that state when you exit todo.create . This is a common problem and can be solved by one of the more complex solutions provided in other answers to this post.

+3
source

My suggestion:

In your configuration add:

 $stateProvider.state('todos', { url: '/todos', controller: 'TodoListController', templateUrl: 'views/todos.html', params : { updated : false } }) 

Read about options with ui-router here

Then in your $ state.go of your todo creation, I would change it to this:

 $scope.create = function() { Todo.create({content: $scope.todo.content}).success(function(data) { $state.go('todos', {updated: true}); }); } 

In your todo controller, I would add this

 if($stateParams.updated == true){ Todo.getAll().success(function(data) { $scope.items = data.results; }); $stateParams.updated = false; } 

This method, instead of relying on a reboot to start the function, you are explicitly looking for a value that will cause a reboot. You can also do the same using the data object, not the params object and set / get values ​​with:

 $state.get('createTodo').data.updated = true; if($state.current.data.updated == true); 

Hope this helps!

Another thought

add a state change listener to the mix:

 $rootScope.$on('$stateChangeSuccess', function(e, toState, toParams, fromState, fromParams) { if(fromState.name === 'createTodo' && toParams.updated == true){ Todo.getAll().success(function(data) { $scope.items = data.results; }); $stateParams.updated = false; } } 
+2
source

This did the trick for me:

 $state.transitionTo('new-state', $state.$current.params, {reload: true}); 
+2
source

Source: https://habr.com/ru/post/980744/


All Articles