Knockout.js mise à Jour ViewModel sur le bouton cliquez sur
Bien, ce n'est pas la meilleure situation description... de toute façon, je suis en train de mettre à jour mon ViewModel mais cela ne fonctionne pas. Par défaut je suis l'obtention de données de fonction de contrôleur et par clic sur un bouton de la part d'une autre fonction dans la même contolleur, mais ViewModel ne contiennent que des données reçues après la première ViewModel d'initialisation.
<script>
function viewModel () {
var self = this;
self.currentPage = ko.observable();
self.pageSize = ko.observable(10);
self.currentPageIndex = ko.observable(0);
self.salesdata = ko.observableArray();
self.newdata = ko.observable();
self.currentPage = ko.computed(function () {
var pagesize = parseInt(self.pageSize(), 10),
startIndex = pagesize * self.currentPageIndex(),
endIndex = startIndex + pagesize;
return self.salesdata.slice(startIndex, endIndex);
});
self.nextPage = function () {
if (((self.currentPageIndex() + 1) * self.pageSize()) < self.salesdata().length) {
self.currentPageIndex(self.currentPageIndex() + 1);
}
else {
self.currentPageIndex(0);
}
}
self.previousPage = function () {
if (self.currentPageIndex() > 0) {
self.currentPageIndex(self.currentPageIndex() - 1);
}
else {
self.currentPageIndex((Math.ceil(self.salesdata().length / self.pageSize())) - 1);
}
}
//Here I'm trying to update ViewModel
self.request = function (uri) {
$.ajax({
url: uri,
contentType: 'application/json',
data: [],
type: 'GET',
cache: false,
success: function (data) {
ko.mapping.fromJS(data.$values, {}, self.salesdata);
}
});
}
}
$(document).ready(function () {
$.ajax({
url: "/api/sales",
type: "GET",
cache: false,
}).done(function (data) {
var vm = new viewModel();
vm.salesdata(data.$values);
ko.applyBindings(vm);
}).error(function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
});
//Here i'm calling for ViewModel update
$(".btn-default").click(function () {
days = $(this).val();
var uri = "/api/sales?days=" + days;
new viewModel().request(uri);
});
});
</script>
Mise à JOUR.
Je chaged bloc de code dans lequel je suis à l'obtention de nouvelles données comme suit:
self.request = function (uri) {
$.getJSON(uri, function (data) {
ko.mapping.fromJS(data.$values, {}, viewModel);
});
}
Malheureusement cela ne fonctionne pas ainsi. Ici, pas toutes les erreurs JS, contrôleur de retour bonne partie de la mise à jour des données.
êtes-vous sûr qu'il n'y a pas d'erreur JavaScript et votre demande appelle gestionnaire de succès?
Après quelques recherches, je suppose que le problème dans cette ligne - ko.la cartographie.fromJS(les données.$valeurs, {}, viewModel); parce que quand j'essaie d'afficher les données via alert (data.$de valeurs), c'est montrer un Objet de données. Et oui, pour éviter d'appeler un viewmodel de nouveau, j'ai utilisé clickeevnt @GoTo suggèrent.
Après quelques recherches, je suppose que le problème dans cette ligne - ko.la cartographie.fromJS(les données.$valeurs, {}, viewModel); parce que quand j'essaie d'afficher les données via alert (data.$de valeurs), c'est montrer un Objet de données. Et oui, pour éviter d'appeler un viewmodel de nouveau, j'ai utilisé clickeevnt @GoTo suggèrent.
OriginalL'auteur andrey.shedko | 2014-04-25
Vous devez vous connecter pour publier un commentaire.
Je suis nouveau à tout cela, mais si je suis en train de lire votre code correctement, vous appelez la fonction de demande sur une nouvelle instance de la vue modèle et non pas celui qui a été liée à un document html. Vous devez faire la demande d'appel sur le modèle de vue que vous avez créé après la phase initiale d'obtenir de l'appel est terminé.
Mise à jour:
Désolé, j'aurais dû être plus précis sur le code, j'ai fait référence. À la fin de votre bloc de code que vous avez le code suivant:
Dans ce code, il semble que chaque fois que le bouton par défaut est sélectionné, un nouveau modèle de vue est créée et la fonction de demande est appelée sur ce modèle de vue.
Dans le document de prêt de la fonction où vous définissez ce qui se passe après la vente de données est chargé, vous avez le code suivant, qui est ce qui crée le modèle de vue que le document html est en fait lié à:
N'y a jamais rien d'appels de la fonction de demande sur ce modèle de vue. Je me demande si vraiment ce que vous voulez, c'est en quelque sorte lier la fonction de demande dans ce modèle de vue sur le bouton par défaut.
Vous avez raison. Mon mauvais. Il y avait deux réponses à cette question, GoTo est très détaillée et de mentionner un point important avec le gestionnaire de clic, alors que je trouve le vôtre un peu générique. La question asker semble avoir besoin d'un peu plus de détails ici. Donc je upvoted GoTo réponse et downvoted la vôtre. Vous avez maintenant édité et l'amélioration de votre réponse, j'ai donc supprimé le downvote. Mon mal de ne pas commenter.
Je downvote parce que cette réponse n'a pas COMMENT mettre à jour l'original viewmodel, je dirais que l'OP est en train de faire.
OriginalL'auteur brader24
Je voudrais essayer de mettre à jour le viewmodel
salesdata
observables, en donnantcontext: self
et à l'aide de la suite desuccess
méthode:EDIT:
Je peux voir que vous avez joint un événement click avec jQuery.
Vous devez utiliser knock-out clck plutôt la liaison:
Et dans le viewmodel
De cette façon, vous pouvez récupérer votre viewmodel au lieu de créer un nouveau comme vous l'avez fait avec
new viewModel().request(uri);
Pour en savoir plus cliquez sur la liaison de voir http://knockoutjs.com/documentation/click-binding.html
Est-il une erreur?
Non, il n'est pas.
Hmm, laissez-moi essayer.
OriginalL'auteur GôTô
Bâtiment légèrement sur la réponse de @brader24 ici:
Dans votre mise à jour du bouton
click
cas, vous utilisez la ligne de code:new viewModel().request(uri);
Ce qui est en train de faire est de créer un nouveau
viewModel
(distincte de celle que vous avez déjà instancié et ont appliqué les liaisons) et le remplissage il est observable tableau avec données par l'intermédiaire de votrerequest
fonction. Il n'affecte pas l'original de votreviewModel
à tous (celui qui a il des liaisons appliquée sur le DOM!). Donc, vous ne verrez pas toutes les erreurs, mais vous ne pouvez pas voir tout ce qui se passe sur la page, car vous n'avez fait que créer un nouveauviewModel
dans la mémoire, le remplir avec des données, et ne rien faire avec elle.Essayer ce code (tout ce qui est dans votre
viewModel
fonction a l'air bien).À l'aide d'un knock-out cliquez sur la liaison plutôt que d'attacher un gestionnaire d'événements click à l'aide de jQuery est généralement de l'itinéraire recommandé, mais il n'est pas nécessaire - de sorte que votre code existant (avec les modifications ci-dessus) devrait fonctionner correctement. Pour plus d'informations, voir L'aide discrète des gestionnaires d'événements dans le knock-out docs
Les gars, vos suggestions look logiquement, mais malheureusement ça ne fonctionne pas.
OriginalL'auteur rwisch45
Bien. Finale de la solution basée sur @GoTo réponse est:
Ici est la façon de faire des appels de fonction dans le viewmodel via un clic databind.
Ici est la fonction. Comme vous pouvez le voir, je vais appeler auto.salesdata au lieu de viewModel. Cette solution fonctionne bien mais de toute façon maintenant j'ai un problème avec le format de données qui est lié de cette manière -
<td data-bind="text: moment($data.whensold).format('DD.MM', 'ru')"></td>
.Je n'ai upvoted de toutes les réponses, donc j'espère que personne ne fait mal.
OriginalL'auteur andrey.shedko