Большинство нокаутов кажется очень интуитивным. Одна вещь, которая мне странна, это то, как работает плагин сопоставления. Я ожидал/надеялся, что смогу накормить его JSON с помощью ajax-звонка и иметь своего рода «динамическую» модель представления, доступную для ссылки в моем HTML-коде.Использование отображения нокаутов для комплекса JSON
description of the mapping plugin даже делает его звук, как это, как это работает:
"If your data structures become more complex (e.g. they contain children or contain arrays) this becomes very cumbersome to handle manually. What the mapping plugin allows you to do is create a mapping from the regular JavaScript object (or JSON structure) to an observable view model."
Но, похоже, вы на самом деле нужно определить модель представления первого в своем коде, а затем вы можете заполнить его после факта использования плагин отображения и некоторые данные JSON. Это правильно?
Конкретный пример того, что я пытался сделать.
Я пытаюсь использовать нокаут с Solr (поисковая система, которая возвращает результаты поиска JSON). Остов структура данных JSON, возвращаемых Solr является:
{
"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": {}
}
На самом деле, это структура я запитывания в моей отображенной модели представления, когда я первый поставил его.
Именно поэтому вы немного понимаете, как данные JSON возвращаются из Solr: массив 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, который пытается разобрать через каждый элемент response.docs, и если выделение части объекта содержит соответствие для поля Id этого документа, я хочу заменить выделенный заголовок, а не заголовок по умолчанию. (В приведенном ниже коде, «Результаты» это имя ViewModel Я отображающей JSON к.)
<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": 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>
Я продолжаю e, чтобы получить такие ошибки:
Message: TypeError: Cannot read property 'Title' of undefined;
Bindings value: text: $root.Results.highlighting()[Id()]['Title']
Не имеет смысла для меня! Мой предыдущий тест показывает, что имеющиеся данные содержат ключ «Заголовок», почему я не могу получить доступ к этим данным?
Редактировать Я создал a jsfiddle, но, разумеется, он работает должным образом. Я не могу воспроизвести свою проблему на jsfiddle. :-(
Редактировать OK Я делаю некоторые успехи здесь, но я все еще очень смущен относительно того, что происходит Сначала я изменил мою отладки 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, а первые два не отображения ни к чему в моих основные моменты() obje ct, поэтому они возвращаются не определены - и поэтому моя попытка потянуть свойство .Title не удалась.
Чтобы подтвердить это, я завернул ko if: $root.Results.highlighting()[Id()]
вокруг этого блока и, наконец, смог получить доступ к свойству .Title во время цикла foreach без ошибки JS.
Это все еще оставляет мне вопрос о том, почему/как есть 3 объекта Results.response.docs, которые зацикливаются. Возможно, привязка foreach запускается 3 раза, а первые 2 раза объект подсветки пуст, а в третий раз он заполняется? Но мне трудно понять, почему это было бы.
Еще одна возможная подсказка: если я вызову вызов ajax во второй раз, не перезагружая страницу, я вижу, что эти 3 «проходы» все возвращают действительный объект каждый раз в журнале консоли. Таким образом, вместо двух undefined
s и объекта, это все три объекта подряд.
На моем выходе HTML, однако, я вижу только одну строку данных. Таким образом, это доказывает, что он не зацикливается на 3 элемента, но фактически запускается 3 раза. Вопрос остается ... ПОЧЕМУ?
Возможно, вы можете взять эту скрипку: http://jsfiddle.net/rniemeyer/ZrY5R/ и получить ее до такой степени, чтобы она напоминала ваш код (обновить или развить его), чтобы мы могли лучше понять вашу структуру , –
@Mason - Я не думаю, что ваш jsfiddle работает так, как вы думаете. Ссылка, которую вы указали выше, не работает для меня. Я проверил последнюю версию той же скрипки, и вы назначаете self.Results дважды, чтобы результат плагина сопоставления был перезаписан. – madcapnmckay
@RPNiemeyer Спасибо за помощь. К сожалению, я сделал некоторые улучшения, как вы можете видеть в моих Редактивах выше, но, тем не менее, пока не можете проиллюстрировать эту проблему в jsfiddle. –