AngularJS - en Utilisant un Service comme un Modèle, ng-repeat pas de mise à jour
Je suis de la création d'un ajax page de recherche qui consistera en une recherche d'entrée de la boîte, la série de filtre de menus déroulants, puis une UL où les résultats sont affichés.
Comme les filtres partie de la recherche sera dans un autre endroit de la page, j'ai pensé que ce serait une bonne idée de créer un Service qui traite de la coordination entre les entrées et les requêtes ajax pour une recherche de serveur-côté. Cela peut ensuite être appelé par un couple de boutons séparés (un pour "searchbox" et les résultats, et une pour les filtres).
La principale chose que je suis mal, c'est obtenir des résultats pour actualiser lors de l'ajax est appelé. Si je mets de l'ajax directement dans le SearchCtrl Contrôleur, il fonctionne très bien, mais quand je bouge l'ajax pour un Service qu'il arrête la mise à jour des résultats lorsque la méthode find sur le Service est appelé.
Je suis sûr que c'est quelque chose de simple, je l'ai raté, mais je n'arrive pas à le voir.
Balisage:
<div ng-app="jobs">
<div data-ng-controller="SearchCtrl">
<div class="search">
<h2>Search</h2>
<div class="box"><input type="text" id="search" maxlength="75" data-ng-model="search_term" data-ng-change="doSearch()" placeholder="Type to start your search..." /></div>
</div>
<div class="search-summary">
<p><span class="field">You searched for:</span> {{ search_term }}</p>
</div>
<div class="results">
<ul>
<li data-ng-repeat="item in searchService.results">
<h3>{{ item.title }}</h3>
</li>
</ul>
</div>
</div>
</div>
AngularJS:
var app = angular.module('jobs', []);
app.factory('searchService', function($http) {
var results = [];
function find(term) {
$http.get('/json/search').success(function(data) {
results = data.results;
});
}
//public API
return {
results: results,
find: find
};
});
app.controller("SearchCtrl", ['$scope', '$http', 'searchService', function($scope, $http, searchService) {
$scope.search_term = '';
$scope.searchService = searchService;
$scope.doSearch = function(){
$scope.searchService.find($scope.search_term);
};
$scope.searchService.find();
}]);
Ici est une ébauche de JSFiddle, j'ai commenté l'ajax et je suis juste mise à jour des résultats de la variable manuellement comme un exemple. Par souci de concision, je n'ai pas inclus le filtre menus déroulants.
Je suis très nouveau pour AngularJS, donc si je vais à ce sujet dans le mauvais sens, merci de me le dire 🙂
OriginalL'auteur Steve Holland | 2013-03-11
Vous devez vous connecter pour publier un commentaire.
Dans votre code HTML, vous avez besoin de faire référence à une propriété définie sur votre contrôleur de dollars de portée. Une façon de le faire est de lier
$scope.searchService.results
àsearchService.results
une fois dans votre contrôleur:Maintenant cette ligne de travail:
Dans votre service, de l'utilisation
angular.copy()
plutôt que d'attribuer un nouveau tableau de référence pourresults
, sinon votre contrôleur de dollars de la portée va perdre sa liaison de données:Violon. En coulisse, j'ai commenté l'appel à find(), de sorte que vous pouvez voir une mise à jour se produire lorsque vous tapez quelque chose dans la boîte de recherche.
angular.copy
partie qui était la pièce manquante du puzzle.C'est tout à fait sens pour moi maintenant. Je l'ai eu à travailler sur 3 autres services, contrôleurs, mais ils étaient juste des tableaux que j'essayais de sorte que la liaison n'a jamais cassé. Si vous remplacez complètement le tableau/objet, vous devez utiliser la copie! Merci!
OriginalL'auteur Mark Rajcok
Le problème, c'est que vous n'êtes jamais mise à jour de vos résultats à l'intérieur de votre portée. Il existe de nombreuses approches pour le faire, mais en fonction de votre code, vous pouvez modifier votre trouver fonction pour renvoyer les résultats:
Vous utilisez un motif de module dans votre 'API publique' de sorte que votre searchService renvoie la trouver fonction et un tableau de résultats, mais vous voulez faire de la fonction trouver à la charge de renvoyer les résultats.
Paramètre de côté, chaque fois que vous appelez doSearch() dans votre périmètre, vous souhaitez mettre à jour les résultats pour ceux retournés par votre searchService
J'ai mis à jour votre jsfiddle avec mes idées, n'est pas fonctionnel, mais j'ai ajouté quelques commments et les journaux pour vous aider à déboguer ce problème. http://jsfiddle.net/XTQSu/3/
find
renvoyer les résultats, parce que les résultats sont nécessaires dans un contrôleur, tandis que lefind()
peut être appelé à partir d'un autre contrôleur. C'est la raison pour garder les résultats locaux pour le Service plutôt que dans le Contrôleur. Ce qui manquait était la liaison des résultats dans le Service du Contrôleur où ils sont utilisés. Comme Mark l'a souligné, je n'avais aucune référence liée, de sorte que c'est pourquoi il n'était pas mise à jour. À l'aide deangular.copy()
gardé la liaison intact lorsque j'ai mis à jour les résultats. Encore une fois, merci d'avoir pris le temps de répondre.OriginalL'auteur odiseo