KnockoutJS Liaison Problème, Impossible de lire la propriété
J'ai ce qui est probablement un simple knock-out, mais je suis un débutant complet. J'ai été jeté sur cette page de code que quelqu'un d'autre a travaillé sur mais jamais fini.
Lorsque cette page se charge tout d'abord, les données sont extraites et la grille principale charge correctement. Le problème vient quand je tente de l'auto-sélectionner le premier enregistrement dans les résultats de sorte qu'une liste détaillée est complété en dessous de la grille.
Quand cela arrive, je reçois le message suivant.
Uncaught TypeError: Impossible de traiter de liaison "text: function (){return sélectionné.RequestLog.Timestamp }" , Message: Impossible de lire la propriété 'Timestamp' undefined
Voici les extraits de code avec lequel je travaille. Les données de retour est à partir d'Entity Framework.
var siteLogModel = function () {
var self = this;
self.errorList = ko.observableArray([]);
self.selected = ko.observable();
self.updateErrorList = function (page) {
jQuery.ajax({
type: "POST",
url: "/Admin/ErrorPage",
data: { pageNum: page },
success: function (result) {
self.errorList(result);
self.selected(result[0]);
//Since we have success, add the click handler so we can get the details about a row by id.
//addRowHandlers();
},
error: function (result) {
jQuery("#status").text = result;
}
});
};
};
C'est la liaison qui essaie de se produire après le chargement des données. RequestLog ne semble pas exister au moment de la liaison, même s'il ne semblent être ok si j'ai mis un point d'arrêt dans la fonction ci-dessus sur la ligne de l'auto.sélectionné(result[0]).
Je pense que c'est une portée de problème mais je ne peux pas pour la vie de moi pense que la meilleure façon de le résoudre. Toute aide serait appréciée.
<div class="param">
<span>Time</span>
<label data-bind="text: selected.RequestLog.Timestamp"></label>
</div>
Mise à JOUR: Voici le document de prêt de la partie.
jQuery(document).ready(function () {
var vm = new siteLogModel();
vm.updateErrorList(0);
ko.applyBindings(vm);
});
OriginalL'auteur Rob Horton | 2014-01-22
Vous devez vous connecter pour publier un commentaire.
Votre
selected
observables ne dispose pas d'un.RequestLog
de la propriété au moment de ko est l'évaluation de l'expression de liaison. Cette erreur est à venir à partir de javascript, pas de ko (si ko encapsule l'exception dans le message d'erreur que vous voyez). Lors de l'exécution,selected.RequestLog === undefined
est vrai, et vous ne pouvez pas invoquer quoi que ce soit sur undefined. C'est comme une référence nulle exception.Il a de sens que si vous appelez
applyBindings
avant l'appel ajax finitions.Un moyen de résoudre ce problème en faisant une angiographie à la place:
Ci-dessus, rien n'est jamais invoquée sur une variable non définie. Votre étiquette affichera "Toujours en attente sur des données" jusqu'à ce que l'appel ajax finit, il se remplira avec le timestamp dès que vous lancez
self.selected(result[0])
.Une autre façon de le résoudre est de garder votre liaison la même, mais en donnant le sélectionné observable une valeur initiale. Vous pouvez laisser tous vos fichiers html, et juste pour cela:
... et vous allez vous retrouver avec le même résultat.
Pourquoi?
Tout moment vous initialisez une observable en faisant quelque chose comme
self.prop = ko.observable()
, la valeur réelle de l'observable estundefined
. Essayez:Donc, pour résumer ce qui se passe:
text: selected.RequestLog.Timestamp
de liaison.Tout ce qui se passe avant votre appel ajax retourne.
Répondre au commentaire #1
Oui, vous pouvez appeler applyBindings après votre ajax succès de l'événement. Toutefois, c'est généralement pas toujours ce que vous devrait faire. Si vous voulez, voici un exemple de la façon dont il pourrait être fait:
Encore un autre moyen serait d'aller de l'avant et impatient de-lier (applyBindings avant l'appel ajax finitions), mais les envelopper votre balisage dans un si contraignant de la sorte:
C'est exact, et j'ai mis à jour ma réponse avec une façon de le faire. Il y a une douzaine de façons différentes que vous pouvez utiliser knock-out. Vous pouvez également consulter la documentation pour la
if
etifnot
liaisons. Vous pouvez simplement être en mesure d'envelopper vos autres liaisons à l'intérieur de l'un de ces à faire ko retard de la liaison jusqu'à ce que après avoir sélectionné votre observable a une valeur.Merci encore pour votre aide. Pour le cercle autour de votre suggestion, j'ai demander (et de montrer ma knock-out inexpérience), où exactement la fonction auto.selectedRequestLogTimestamp placés? À l'intérieur du var siteLogModel = function (), je suppose. J'ai essayé cela, et bien que je n'ai plus reçu de mon erreur, je n'ai jamais vu toutes les données et le texte par défaut est jamais affiché.
Oui, c'est là où il est censé aller. Un calculées fonctionne presque comme un fait observable -- quand pas les arguments sont passés, il faut suffit de retourner une valeur. Honnêtement, je ne peux pas dire sans définition de points d'arrêt dans le JS pourquoi il n'est pas appelé. Avez-vous mis comme le dernier membre de la viewmodel ctor?
Nan je ne l'avais pas. Je n'ai juste essayer ce que, sur un coup de tête. J'ai mis ma vm déclaration de variable à l'extérieur de mon document.prêt de la fonction au niveau de la page. Alors que j'ai référencé vm.sélectionné dans mes liaisons. Cela semble être au travail jusqu'à présent. Ne qui fait sens pour vous ou vous pensez que je suis hors de la base en faisant cela?
OriginalL'auteur danludwig