我正在开发一个 TVML 应用程序。其中一个屏幕显示了供用户输入关键字的搜索表单。输入的文本将与包含现有每个项目的先前存在的 JSON 文件进行比较。在过滤可用结果后,这些用于通过使用外部 XML 文件构建 XML 节点,然后将它们导入到搜索文档中,特别是导入到 Id 为“结果”的部分。问题是,如果我直接输入搜索词,搜索就会发生。但是,如果我一个字母一个字母地输入(允许在每个字母之后进行搜索),那么应用程序就会崩溃并且我会收到以下错误:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
terminating with uncaught exception of type NSException
(索引号和范围因结果不同而异)
以下是我目前拥有的文件:
搜索.tvml
<?xml version="1.0" encoding="UTF-8" ?>
<document>
<head>
<style>
.company {
font-size: 26;
}
</style>
</head>
<searchTemplate>
<searchField />
<collectionList>
<grid>
<header>
<title>Search Results</title>
</header>
<section id="results">
</section>
</grid>
</collectionList>
</searchTemplate>
</document>
搜索结果.tvml
<lockup template="video.tvml" presentation="push" id="{{id}}">
<img src="https://path_to_images/{{path}}/{{image}}.jpg" width="380" height="266" alt="{{name}}"/>
<title>{{name}}</title>
<subtitle class="company">{{company}}</subtitle>
</lockup>
SearchHandler.js
class SearchHandler {
constructor(resourceLoader) {
this._resourceLoader = resourceLoader;
this.searchDatabase = "";
}
enableSearchForDoc(doc) {
this._addSearchHandlerToDoc(doc);
}
_addSearchHandlerToDoc(doc) {
var searchFields = doc.getElementsByTagName('searchField');
for (var i = 0; i < searchFields.length; ++i) {
var searchField = searchFields.item(i);
var keyboard = searchField.getFeature("Keyboard");
keyboard.onTextChange = this._handleSearch.bind(this, keyboard, doc);
}
}
_handleSearch(keyboard, doc) {
// Get the text entered
var searchString = keyboard.text;
// Blank results array
var results = [];
// Search only if text entered has more than one character
if (searchString.length > 1) {
results = this.searchVideosForString(searchString, this.searchDatabase);
}
// Get the result nodes (lockups) from the results obtained
var resultNodes = this._renderResults(results);
// Get a reference to the "results" section in search.tvml
var resultContainer = doc.getElementById("results");
// If such section exists
if (resultContainer) {
// remove previous results
while (resultContainerChildren > 0 ) {
resultContainer.removeChild(resultContainer.lastChild);
resultContainerChildren--;
}
// Add each lockup node to the results section
if (resultNodes.length > 0) {
resultNodes.forEach(function(resultNode) {
doc.adoptNode(resultNode);
resultContainer.appendChild(resultNode);
});
}
}
}
_renderResults(results) {
var resourceLoader = this._resourceLoader;
// Get an XML node (lockup) for each of the results found
// Results will be used as data for the XML
var rendered = results.map(function(result) {
var doc = resourceLoader.getRenderedDocument("searchResults.tvml", result);
return doc.documentElement;
});
// Return the array of lockup nodes
return rendered;
}
searchVideosForString(searchString, data) {
var sourceData = data;
var results = []
results = sourceData.filter(function(v) {
var title = v.name;
var show = v.showname;
var company = v.company;
return title.toLowerCase().includes(searchString.toLowerCase()) || show.toLowerCase().includes(searchString.toLowerCase()) || company.toLowerCase().includes(searchString.toLowerCase())
});
console.log("SEARCH RESULTS: ", results);
return results;
}
}
我一直在使用 Safari 控制台监视 searchVideosForString 方法的结果,我发现,例如,如果我尝试搜索存在于完整结果中的“Parry”,如果我输入单词“Par ",控制台为搜索结果显示一个包含 18 个对象的数组。如果我打开显示三角形,它会显示这 18 个对象中的每一个。如果我在搜索中添加一个字符来查找“Parr”,那么应用程序就会崩溃。控制台为搜索结果显示一个包含 1 个对象的数组,但如果我打开显示三角形,它是空的,我看不到实际对象是什么。
我尝试在 handleSearch 方法中删除部分代码。如果我删除下面的所有内容
var resultContainer = doc.getElementById("results");
然后我可以在搜索框中输入任何文本而不会出现任何问题,并且控制台会显示适当的搜索结果,无论它们有多少。
似乎问题发生在这一行:
doc.adoptNode(resultNode);
但我无法弄清楚索引超出范围异常的原因和来源。