Données motif de chargement pour knockoutjs
-
27-10-2019 - |
Question
Je suis en train de comprendre si KnockoutJS travaillera pour mon application. Mon modèle de données (simplifié) se présente comme suit:
function topic(data) {
this.id = data.id;
this.queries = ko.observableArray([]);
}
function query(data) {
this.id = data.id;
this.text = data.text;
this.searcher = data.searcherId;
this.postings = ko.observableArray([]);
}
function posting(data, query) {
this.documentId = data.docid;
this.rank = data.rank;
this.snippet = data.snippet;
this.score = data.score;
this.query = query;
this.document = null;
}
function document(data, topic) {
this.id = data.id;
this.url = data.url;
this.topic = topic;
}
Pour une topic
donnée, j'ai une ou plusieurs instances de query
. Chaque requête contient une liste des instances de posting
. Chaque posting
fait référence à un document. Plus d'un posting
peut se référer à un document
donné tant que les instances de posting
appartiennent à différentes instances de query
.
Si un posting
fait référence à un nouveau document (un pas encore récupéré par un query
) Je voudrais créer une nouvelle instance; si le document
existe déjà (ids sont uniques), je voudrais réutiliser.
Je peux voir des alternatives possibles pour structurer les données JSON renvoyées par le serveur:
- Lors de la sérialisation messages, d'abord sérialiser une liste de tous les documents, et mettre à jour la liste des documents de maître avec eux. Ensuite, envoyez messages avec des références à documents ids.
- sérialisation chaque document complètement comme propriété d'un affichage, et ensuite déterminer si cette entrée est redondante. Ajouter les entrées non redondantes à la liste principale.
Qu'est-ce qu'un modèle raisonnable pour sérialisation les données? Y at-il un peu de magie plugin mapping qui exprimerait cette succinctement? Je contrôle sur le serveur qui est la génération du JSON, et peut structurer que d'une façon qui est logique.
Merci,
Gene
La solution
Here's what I wound up doing to implement option 1:
function idField(data) {
return ko.utils.unwrapObservable(data.id);
}
function createMapping(type, context) {
return {
key: idField,
create: constructor(type, context)
}
}
function constructor(type, context) {
return function(options) {
return new type(options.data, context);
}
}
function createReferenceMapping(collection) {
return {
key: idField,
create: lookup(collection)
}
}
function lookup(collectionOrClosure) {
return function(options) {
var collection = (typeof collectionOrClosure == 'function') ? collectionOrClosure() : collectionOrClosure;
var object = collection.findById(options.data.idref);
if (object == null)
console.log("Error: Could not find object with id " + options.data.idref + " in ", collection);
return object;
}
}
I call this code as follows:
var mapping = {
people: createMapping(Searcher),
topics: createMapping(Topic, this),
activeTopic: createReferenceMapping(function(){return self.topics();})
};
this.dataChannel.loadModel(function(data) {
ko.mapping.fromJS(data, mapping, this);
}
This takes care both of creating new instances (via the constructor
function) and looking up existing ones via lookup
.
Autres conseils
Checkout entityspaces.js, there's a video you can watch, it supports full hierarchcial data models and will even generate your WCF JSON service, it supports REST API's as well.
A Javascript ORM (Data Access) Framework that uses Knockout