gpt4 book ai didi

knockout.js - 对复杂的JSON使用Knockout映射

转载 作者:行者123 更新时间:2023-12-02 00:23:18 25 4
gpt4 key购买 nike

大多数的淘汰赛似乎都很直观。不过,令我感到奇怪的是,映射插件的工作方式。我期望/希望我能够从ajax调用中馈入JSON,并拥有一种“动态” View 模型,该模型可在HTML中引用。

description of the mapping plugin甚至听起来像这样:

“如果您的数据结构变得更加复杂(例如,它们包含
子级或包含数组),这变得非常麻烦
手动。映射插件允许您执行的操作是创建映射
从常规JavaScript对象(或JSON结构)到
可观察的 View 模型。”

但是看来您实际上确实需要先在代码中定义 View 模型,然后可以在使用映射插件和一些JSON数据之后填充该 View 模型。这是正确的吗?

我正在尝试做的一个具体例子。

我正在尝试将淘汰赛与Solr(返回JSON搜索结果的搜索引擎)一起使用。 Solr返回的JSON数据的框架结构为:

  {
"responseHeader": {
"status": 0,
"QTime": 0,
"params": {
"facet": "true",
"facet.field": "System",
"q": "testphrase",
"rows": "1",
"version": "2.2"
}
},
"response": {
"numFound": 0,
"start": 0,
"maxScore": 0.0,
"docs": []
},
"facet_counts": {
"facet_queries": {},
"facet_fields": {
"System": []
},
"facet_dates": {},
"facet_ranges": {}
},
"highlighting": {}
}

实际上,这就是我第一次设置映射 View 模型时要使用的结构。

如此您就对Solr如何返回JSON数据有了一点了解:response.docs数组包含一个哈希数组,其中哈希数据由索引文档数据的键/值组成。数组中的每个哈希都是在搜索结果中返回的一个文档。

这部分似乎映射良好。

JSON的“突出显示”部分是导致我出现问题的原因。当我尝试引用HTML中的突出显示字段时,出现ReferenceErrors。这是JSON中突出显示字段的外观示例:
"highlighting": {
"2-33-200": {
"Title": ["1992 <b>Toyota</b> Camry 2.2L CV Boots"]
},
"2-28-340": {
"Title": ["2003 <b>Toyota</b> Matrix 2.0L Alignment"]
},
"2-31-2042": {
"Title": ["1988 <b>Toyota</b> Pickup 2.4L Engine"]
}
}

我的HTML中有一个foreach试图解析每个response.docs元素,并且如果对象的突出显示部分包含该文档的ID字段的匹配项,我想替换突出显示的Title而不是默认Title。 (在下面的代码中,“结果”是我要将JSON映射到的 View 模型的名称。)
<div id="search-results" data-bind="foreach: Results.response.docs">
<div data-bind="attr: { id: 'sr-' + Id }" class="search-result">
<h3 class="title"><a data-bind="html: (($root.Results.highlighting[Id]['Title'] != undefined) ? $root.Results.highlighting[Id]['Title'] : Title), attr: {href: Link}"></a></h3>
<span class="date" data-bind="text: DateCreated"></span>
<span class="snippet" data-bind="html: Snippet"></span>
</div>
</div>

当我尝试使用它时,总是会出现此错误:
Uncaught Error: Unable to parse bindings.
Message: TypeError: Cannot read property 'Title' of undefined;
Bindings value: html: (($root.Results.highlighting[Id]['Title'] != undefined) ? $root.Results.highlighting[Id]['Title'] : Title), attr: {href: Link}

我已经尝试过各种关于如何引用数据的方法,但是似乎无法访问它。

编辑我正在取得一些进展。在映射定义中,我现在指定“highlighting”,如下所示:
"highlighting": ko.observable({})

不仅仅是将突出显示设置为{}。现在,当我进行映射时,至少可以对突出显示的数据进行一些观察。但是我仍然看到奇怪的错误。

我已经简化了测试HTML代码,只为每个搜索结果吐出了突出显示的数据:
<div id="search-results" data-bind="foreach: Results.response.docs">
<pre data-bind="text: JSON.stringify(ko.toJS($root.Results.highlighting()[Id()]), null, 2)"></pre>
</div>

现在返回多个 <pre>标签,如下所示:
{
"Title": [
"1992 <b>Toyota</b> Camry 2.2L CV Boots"
]
}

但是,如果我将HTML代码更改为此:
<pre data-bind="text: $root.Results.highlighting()[Id()]['Title']"></pre>

我继续收到这样的错误:
Message: TypeError: Cannot read property 'Title' of undefined;
Bindings value: text: $root.Results.highlighting()[Id()]['Title']

对我来说毫无意义!我之前的测试表明,可用数据确实包含“标题”键,为什么我不能访问该数据?

编辑我创建了 a jsfiddle,但是当然...它可以按预期工作。我无法在jsfiddle上重现我的问题。 :-(

编辑好,我在这里取得了一些进展,但是对于正在发生的事情仍然很困惑。首先,我将调试HTML更改为:
<div id="search-results" data-bind="foreach: Results.response.docs">
<pre data-bind="text: console.log($root.Results.highlighting()[Id()])"></pre>
</div>

然后,我提交了ajax调用,并且在Chrome控制台中注意到了以下输出:
undefined
undefined
> Object

因此出于某种原因, foreach循环遍历了3个Results.response.docs,而前两个未映射到我的highlights()对象中的任何内容,因此它们返回的是undefined,这就是为什么我尝试拉出。标题属性失败。

为了确认这一点,我在该块周围包裹了 ko if: $root.Results.highlighting()[Id()],终于能够在foreach循环中访问.Title属性而没有JS错误。

这仍然让我想到为什么/如何有3个Results.response.docs对象被循环的问题。也许foreach绑定(bind)正在运行3次,而前2次是突出显示对象为空,而第三次是最后被填充?但是我很难弄清楚为什么会这样。

另一个可能的线索:如果我第二次触发ajax调用而没有重新加载页面,则可以看到这3次“传递”每次在控制台日志中都返回一个有效的Object。因此,代替了三个 undefined和一个Object,而是连续三个对象。

但是,在我的HTML输出中,我只看到一行数据。因此,这似乎证明它没有循环3个元素,但实际上正在运行3次。问题仍然存在……为什么?

最佳答案

映射插件正在按预期工作。您的问题很简单,就是您期望插件在对象的每个级别上创建可观察的对象。这不是插件的工作方式。它只会为“叶”属性创建可观察的对象。因此,在您的情况下,$root.Results.highlighting并未创建为可观察的。但是,文档上的id属性是作为可观察对象创建的,因此解决方案是。

$root.Results.highlighting[Id()]

我相信您可能会感到困惑,因为您的小提琴之一正在分配self.Results两次使它似乎以一种方式工作,而实际上是在掩盖问题。

这是工作版本

http://jsfiddle.net/madcapnmckay/UaBKe/

希望这可以帮助。

关于knockout.js - 对复杂的JSON使用Knockout映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9985490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com