Question

Je crée une application utilisant la bibliothèque KnockoutJS très lisse, mais j'ai rencontré un accroc. Sur la page html, j'ai un contrôle <select> clair que je veux charger des données JSON renvoyés d'un service Web.

Je définissiez le tableau observable comme suit:

var laborRow = function () {
    this.positions = ko.observableArray([]);
};

Lorsque la page se charge, l'appel ajax est faite et les données sont renvoyées. Dans le rappel, je fais ce qui suit:

    success: function (msg) {
        laborRow.positions = msg;
    }

sur la base des documents KO, j'attendre à ce que je mettrais le résultat comme ceci:

laborRow.positions(msg);

Cependant, cela jette juste une erreur indiquant que « dans laborRow.positions pas une fonction »

Le modèle dans le code HTML est comme suit:

<tbody data-bind='template: {name: "laborRowTemplate", foreach: laborLine}'> </tbody> 
</div>
  <script type="text/html" id="laborRowTemplate"> 
        <tr>

          <td><select data-bind='options: positions, optionsText: "Title", optionsCaption: "select", value: selectedPosition '></select></td>

        </tr>
    </script>

L'objet laborRow est une propriété sur le ViewModel qui est lié à la page. Pour une raison quelconque, cela ne fonctionne pas. Pour ajouter une autre ride, si j'ajouter du code à coup d'oeil dans la observableArray et imprimer un morceau de données, les données sont là-dedans. Donc, il est chargé avec succès.

Toute pensée serait grandement appréciée.

Le code complet pour mon exemple le cas:

var laborRow = function () {
    this.positions = ko.observableArray([]);    
};

var projectEstimate = function () {
    this.laborLine = ko.observableArray([new laborRow()]);

};

var projectViewModel = new projectEstimate();
ko.applyBindings(projectViewModel);

//and the code in the callback function on ajax success

 success: function (msg) {
                laborRow.positions = msg;
                //laborRow.positions(msg); **this does not work - error is laborRow.positions is not a function**
            },

Et le code html:

 <tbody data-bind='template: {name: "laborRowTemplate", foreach:
laborLine}'> </tbody>

  <script type="text/html" id="laborRowTemplate">
        <tr>
          <td><select data-bind='options: positions, optionsText:
"Title",  optionsCaption: "select", value: selectedPosition '></
select></td>

        </tr>
    </script> 

Enfin, grâce aux commentaires de Sean ci-dessous, j'ai pu le faire fonctionner en modifiant le code dans la fonction de rappel comme suit:

success: function (msg) {
    projectViewModel.laborLine()[(projectViewModel.laborLine().length-1)].positionList(msg);
}
Était-ce utile?

La solution

Le problème est que vous n'avez pas réellement créé votre modèle:

var laborRow = function () {
    this.positions = ko.observableArray([]);
    // will only be called if you call var some_var = new laborRow()
};

Changer votre fonction à un objet nu (comme le montre le knock-out docs ):

var laborRow = {
    positions: ko.observableArray([])
};

Et vous serez en mesure d'appeler laborRow.positions(msg); et le faire fonctionner.


EDIT

Sur la base du nouveau code, laborRow est toujours pas instancié - si vous mettez var laborRow ailleurs dans votre code (autour de la demande de paiement ajax, peut-être), alors vous aurez envie de vous assurer que votre apparence de la pile d'appel comme celui-ci:

projectViewModel.laborLine()[0].positions() 
// This will return the array you're looking for.
// The key is that laborLine is a `getter` not an attribute

J'ai été mordu par le bug « variables ko sont getters pas de attributes » à plusieurs reprises ... qui pourrait se passer avec votre code?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top