【问题标题】:data loading pattern for knockoutjs淘汰赛的数据加载模式
【发布时间】:2012-01-12 10:14:20
【问题描述】:

我正在尝试了解 KnockoutJS 是否适用于我的应用程序。我的数据模型(简化)如下:

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

对于给定的topic,我有一个或多个query 实例。每个查询都包含一个posting 实例列表。每个posting 指的是一个文档。只要posting 实例属于不同的query 实例,就可以有多个posting 引用给定的document

如果posting 引用一个新文档(尚未被任何query 检索到)我想创建一个新实例;如果document 已经存在(ID 是唯一的),我想重新使用它。

我可以看到一些可能的替代方案来构建服务器返回的 JSON 数据:

  1. 序列化过帐时,首先序列化所有文档的列表,并使用它们更新主文档列表。然后,发送引用文档 ID 的帖子。
  2. 将每个文档完全序列化为发布的属性,然后确定该条目是否多余。将非冗余条目添加到主列表。

序列化数据的合理模式是什么?是否有一些映射插件的魔法可以简洁地表达这一点?我可以控制生成 JSON 的服务器,并且可以以任何有意义的方式构建它。

谢谢,

基因

【问题讨论】:

  • 基因,这个问题相当广泛和主观。我不清楚我们可以客观回答哪些具体问题。
  • 嗯,我一直在寻找关于成语和最佳实践的指导。我实施了策略 #1,因为我可以控制服务器。

标签: javascript knockout.js knockout-mapping-plugin


【解决方案1】:

这是我最终为实现选项 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;
    }
}

我这样称呼这段代码:

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

这需要注意创建新实例(通过constructor 函数)和通过lookup 查找现有实例。

【讨论】:

    【解决方案2】:

    检查 entityspaces.js,有一个视频可以观看,它支持完整的分层数据模型,甚至可以生成 WCF JSON 服务,它还支持 REST API。

    使用 Knockout 的 Javascript ORM(数据访问)框架

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

    【讨论】:

    • 我是否正确地说您创作了 EntitySpaces?如果是这样,请说明您这样做了(并且对于您的其他答案也是如此)。请阅读有关此问题的常见问题解答:stackoverflow.com/faq#promotion
    • 对不起,我不知道,谢谢你的链接。是的,我自己、David 和 Scott 是 EntitySpaces 的创造者。
    猜你喜欢
    • 1970-01-01
    • 2013-06-26
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多