문제

I am trying to understand if KnockoutJS will work for my application. My data model (simplified) is as follows:

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;
}

For a given topic, I have one or more query instances. Each query contains a list of posting instances. Each posting refers to a document. More than one posting can refer to a given document as long as the posting instances belong to different query instances.

If a posting refers to a new document (one not yet retrieved by any query) I would like to create a new instance; if the document already exists (ids are unique), I would like to re-use it.

I can see some possible alternatives for structuring the JSON data returned by the server:

  1. When serializing postings, first serialize a list of all documents, and update the master document list with them. Then, send postings with references to document ids.
  2. Serialize each document completely as a property of a posting, and then figure out if that entry is redundant. Add non-redundant entries to the master list.

What is a reasonable pattern for serializing the data? Is there some mapping plugin magic that would express this succinctly? I have control over the server that's generating the JSON, and can structure that in any way that makes sense.

Thanks,

Gene

도움이 되었습니까?

해결책

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.

다른 팁

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

https://github.com/EntitySpaces/entityspaces.js#readme

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top