2015-01-09 12 views
6

Sono AngularJS di apprendimento e quadro ionico utilizzando questo tutorial:

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

Tutto funziona bene fino al punto quando creo un nuovo elemento in lo stato createTodo e quindi chiamare $ state.go ('Todos') per tornare al mio elenco di oggetti, ecco il codice per il controller Todo creare:

.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}); 
     }); 
    } 
}]) 

ecco il codice per il controller lista articolo:

.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); 
    }; 
}]) 

Qui sono stati configurati

All'avvio dell'applicazione, il metodo della TodoListController viene richiamato grazie all'ultima linea aggiunta e la fine del metodo .run nei principali app.js (o almeno questo è la mia comprensione):

.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'); 
}) 

mio problema è che, non appena il nuovo elemento viene creato e invoco $ state.go ('Todos') dalla TodoCreateController, mi riporta alla elenco articoli ma il nuovo oggetto non è presente e il metodo o f TodoListController non viene mai richiamato, pertanto l'elenco non è aggiornato.

Come posso aggiornare l'elenco nello stato 'todos' dopo che è stato creato un nuovo elemento?

risposta

12

ho trovato una soluzione piuttosto elegante:

Dentro il mio TodoListController io definisco un listener di eventi come questo:

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

Poi viene il metodo updateList()

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

E infine nella TodoCreateController I $ emetto l'evento verso l'alto non appena l'oggetto viene creato e destra prima di cambiare stato

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

E voilà! L'elenco viene aggiornato di conseguenza e ora può utilizzare lo stesso evento se elimino o aggiornare una voce di elenco

2

Il mio suggerimento:

nella configurazione aggiungere:

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

Leggi su params con ui-router here

Poi, nel tuo $ state.go del vostro creare todo vorrei cambiarlo a questo:

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

Nel controller di Todo vorrei aggiungere questo

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

In questo modo piuttosto che contare sulla ricarica per eseguire la funzione che si sta esplicitamente alla ricerca di un valore che attiverà la ricarica. È anche possibile fare la stessa cosa utilizzando l'oggetto data piuttosto che l'oggetto params e impostare/recuperare i valori tramite:

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

Spero che questo aiuti!

un altro pensiero

aggiungere un cambiamento di stato ascoltatore al 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; 
    } 
} 
+0

Grazie Jacob, ma tutti i suggerimenti presuppongono che il codice all'interno di TodoListController verrà eseguito dopo l'aggiunta di un nuovo elemento. Ma il problema rimane. quando chiamo $ state.go() all'interno di TodoCreateController, lo stato cambia ma il codice all'interno di TodoListController è ** non eseguito ** e non so perché –

+0

Inserendo il codice all'interno del rootScope.on statechangesuccess verrà richiamato il codice. Provalo e fammi sapere –

+0

Lo faccio davvero ma il codice è chiamato come 3 volte. In ogni caso, il tuo suggerimento mi ha dato un'idea che ha funzionato bene. Grazie mille per il tuo feedback –

2

Questo ha fatto il trucco per me:

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

Grazie! Funziona anche per me. – Jaxedin

+0

Assegna un cattivo effetto UX, quindi si sente come un aggiornamento della pagina. –

3

Ho incontrato questo e problemi simili e si è scoperto la cache di vista ionica era spesso il motivo per cui non si chiamava il codice del controller quando si tornava a una vista memorizzata nella cache.

Possibile soluzione

Quando separare il codice di controllo in one-time-inizializzazione e codice in esecuzione quando viene immesso vista, in genere si finisce con i controllori di simile a questo:

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

$scope.$on('$ionicView.beforeEnter', function() { 
    $scope.updateList(); 
}); 

Questo dovrebbe risolvere il tuo problema senza dover attivare eventi o aggiungere parametri o dati alla rotta.

alternativa

È possibile disabilitare vista cache in diversi modi:

  • aggiungere cache: false per la definizione dello stato
  • aggiungere cache-view="false" alla html <ion-view ...>
  • caching disabilitazione con $ionicConfigProvider.views.maxCache(0); (non lo consiglio)

Pitfall quando si utilizza Sotto Uniti

Non

nel tuo caso, ma se la modifica/creazione di file in sub-Stati (per esempioafferma todo per la lista e todo.create per la creazione di un nuovo todo), v'è un ulteriore problema provenienti da ui-router:

Durante la navigazione da todo.create affermare todo, non sarà "giustiziato" il tuo super-Stato todo, perché sei già in questo stato quando provieni da todo.create. Questo è un problema comune e può essere risolto con una delle soluzioni più complesse fornite in altre risposte a questo post.

Problemi correlati