Knockout.js: impossible d’parsingr les liaisons à partir de JSON

J’ai un modèle de vue qui extrait JSON via AJAX et crée une nouvelle tâche, mais Knockout continue de me donner une erreur de liaison.

Si je code en dur les données provenant du serveur directement dans mon modèle de vue, je ne reçois aucune erreur.

Mon modèle de vue crée une nouvelle tâche, qui comporte un identifiant, une question et un certain nombre d’alternatives, qui comporte en soi un texte et un drapeau booléen correct.

Le code suivant fonctionne parfaitement bien:

function Task(data) { var self = this; self.id = data.id; self.question = ko.observable(data.question); var alts = new Array(); $(data.alternatives).each(function(index){ alts.push(new Alternative(data.alternatives[index].alternative, data.alternatives[index].correct)); }); self.alternatives = ko.observableArray(alts); } function Alternative(alternativeText, correctAnswer) { var self = this; self.alternative = ko.observable(alternativeText); self.correct = ko.observable(correctAnswer); } function TaskViewModel() { var self = this; var data = { id: 5, question: 'test', alternatives: [{ alternative: 'alt 1', correct: false },{ alternative: 'alt 2', correct: true },{ alternative: 'alt 3', correct: false }] }; self.task = new Task(data); } 

Mais si j’excange la variable de data codée en dur avec les données réelles du serveur:

 function TaskViewModel() { var self = this; $.getJSON('/data', function(data){ self.task = new Task(data); }); } 

Knockout me donne cette erreur:

 Error: Unable to parse bindings. Message: ReferenceError: Can't find variable: task; Bindings value: value: task.question 

Les données de l’URL ressemblent à ceci:

 {"id":5,"question":"test","alternatives":[{"alternative":"alt 1","correct":false},{"alternative":"alt 2","correct":true},{"alternative":"alt 3","correct":false}]} 

Je n’arrive pas à comprendre pourquoi cela ne fonctionne pas: /

Votre modèle de vue ne dispose pas réellement d’une propriété de task au moment où vos liaisons sont appliquées. Vous devez lui donner quelque chose à lier.

Il y a plusieurs façons de gérer cela.

Le moyen le plus simple serait probablement de rendre la task observable et de la définir comme le résultat de l’appel ajax. Vous devrez peut-être ajuster vos liaisons pour tenir compte de ce changement.

 function TaskViewModel() { var self = this; self.task = ko.observable(); $.getJSON('/data', function(data){ self.task(new Task(data)); }); } 

Une option plus flexible consisterait à append une méthode d’initialisation distincte pour vos objects Task et à définir la tâche (non initialisée). Ensuite, à la suite de l’appel ajax, appelez la méthode d’initialisation pour l’initialiser. Vous devrez bien sûr ajuster le code d’initialisation pour vos objects de tâches.

 function TaskViewModel() { var self = this; self.task = new Task(); $.getJSON('/data', function(data){ self.task.init(data); }); } function Task() { var self = this; self.id = ko.observable(); self.question = ko.observable(); self.alternatives = ko.observableArray(); self.init = function (data) { self.id(data.id); self.question(data.question); self.alternatives(ko.utils.arrayForEach(data.alternatives, function (item) { return new Alternative(item.alternative, item.correct); })); }; } 

Cet article contient un certain nombre de façons de gérer la liaison lorsque la source est null.

Liaison KnockoutJS lorsque la source est null / undefined

Si vous êtes d’accord avec la disparition de votre interface utilisateur non liée, je vous recommande d’utiliser with

Si selectedItem est null, l’élément ne sera même pas affiché.