2015-01-09 17 views
6

ruft ich bin Lernen AngularJS und ionische Rahmen dieses Tutorial mit:

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

Alles funktioniert gut, bis der Punkt, wenn ich ein neues Element erstellen in der createTodo Zustand und rufen Sie dann $ state.go (‚todos‘) auf meinen Artikel Liste zurück zu gehen, hier ist der Code für die Todo-Controller erstellen:

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

hier ist der Code für die Artikelliste 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); 
    }; 
}]) 

Hier sind die Zustände

konfigurierten, wenn die Anwendung gestartet wird, wird die Methode des TodoListController dank aufgerufen auf die letzte Zeile und das Ende der .run Methode in dem Haupt app.js hinzugefügt (oder zumindest das ist mein Verständnis):

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

Mein Problem ist, dass, sobald das neue Element erstellt wird, und ich rufe $ state.go (‚todos‘) von dem TodoCreateController, es erinnert mich an den Artikelliste aber der neue Artikel ist nicht da und die Methode o f Der TodoListController wird nie aufgerufen, weshalb die Liste nicht mehr aktuell ist.

Wie kann ich die Liste im 'todos'-Zustand aktualisieren, nachdem ein neues Element erstellt wurde?

Antwort

12

ich eine recht elegante Lösung gefunden:

Inside my TodoListController ich einen Ereignis-Listener wie folgt definieren:

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

dann kommt die update() -Methode

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

Und schließlich in dem TodoCreateController ich das Ereignis emittieren $ nach oben, sobald der Artikel erstellt und direkt vor

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

Und voila Zustand ändern! Die Liste entsprechend aktualisiert, und ich kann jetzt das gleiche Ereignis verwenden, wenn ich

2

Mein Vorschlag:

In der config hinzu:

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

Lesen Sie mehr über params mit ui-Router here

todo Dann in Ihrem $ state.go Ihrer schaffen würde ich es ändern dazu:

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

In Ihrem Todo Controller würde ich dies hinzufügen

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

Auf diese Weise und nicht auf der Reload-Zählen die Funktion, die Sie explizit die Suche nach einem Wert auszuführen, der den reload auslösen. Sie können auch das Gleiche tun, um die data Objekt anstatt das params-Objekt und setzen/Werte abrufen über:

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

hoffe, das hilft!

Ein anderer Gedanke

eine Zustandsänderung Zuhörer in den 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

Danke Jacob, aber alle Vorschläge gehen davon aus, dass der Code in der TodoListController ausgeführt wird, nachdem ein neues Element hinzugefügt wurde. Aber das Problem bleibt bestehen. Wenn ich innerhalb von TodoCreateController $ state.go() aufruft, ändert sich der Status, aber der Code in TodoListController wird ** nicht ausgeführt ** und ich weiß nicht warum –

+0

Durch das Einfügen des Codes in den rootScope.on statuschangesuccess wird der Code aufgerufen. Probieren Sie es aus und lassen Sie es mich wissen –

+0

Ich tue zwar, aber der Code wird wie 3 Mal aufgerufen. Auf jeden Fall hat dein Vorschlag mir eine Idee gegeben, die gut funktioniert hat. Vielen Dank für Ihr Feedback –

2

Dies hat den Trick für mich ein Listenelement löschen oder aktualisieren:

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

Vielen Dank! Funktioniert auch für mich. – Jaxedin

+0

Bietet einen schlechten UX-Effekt, der sich wie eine Seitenaktualisierung anfühlt. –

3

ich diese und ähnliche Probleme haben und es stellte sich heraus, dass ionic view caching war oft der Grund dafür, den Controller-Code nicht aufzurufen, wenn er zu einer zwischengespeicherten Ansicht zurückkehrt.

Mögliche Lösung

Wenn der Controller-Code in einmalige Initialisierung und Code Trennung ausgeführt wird, wenn Ansicht eingegeben wird, beenden Sie in der Regel mit Controllern wie folgt aussehen:

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

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

Dies sollte Ihr Problem lösen, ohne Ereignisse auszulösen oder der Route Parameter oder Daten hinzuzufügen.

Alternative

Es ist möglich Ansicht Caching auf unterschiedliche Weise zu deaktivieren:

  • hinzufügen cache: false dem Stand Definition
  • hinzufügen cache-view="false" zum html <ion-view ...>
  • deaktivieren Caching mit $ionicConfigProvider.views.maxCache(0); (würde dies nicht empfehlen)

Pitfall, wenn Sub-Staaten mit

nicht in Ihrem Fall, aber wenn die Bearbeitung/Erstellung von Reihen in Teilstaat (zaus Richtung ui-Router erklärt todo für die Liste und todo.create für eine neue Aufgabe zu schaffen), gibt ein zusätzliches Problem ist:

Wenn von todo.create Navigation todo, Ihr Superstaat todo zu erklären, wird nicht „ausgeführt“ werden, weil Sie bereits in diesem Zustand sind, wenn Sie von todo.create kommen. Dies ist ein häufiges Problem und kann durch eine der komplizierteren Lösungen in anderen Antworten auf diesen Beitrag gelöst werden.

Verwandte Themen