Ошибка нокаута: не удается найти закрывающий тег комментария для соответствия

Это может показаться дублирующимся вопросом, но ни один из ответов не помог мне. У меня есть следующий HTML (это шаблон Razor, но здесь нет особенностей Razor).

<p class="search-results-summary">
    Results 
    <!-- ko if: SearchTerms.Query -->
    for <span data-bind="html: SearchTerms.Query"></span>
    <!-- /ko -->
    <!-- ko if: SearchTerms.Names -->
    for Names <span data-bind="html: SearchTerms.Names.join(', ')"></span>
    <!-- /ko -->
    <!-- ko if: SearchTerms.Location && AlternativeLocations && AlternativeLocations.length -->
        within <span data-bind="text: SearchTerms.LocationRadio"></span>
        miles of <span data-bind="html: SearchTerms.Location"></span>. 
        <!-- ko if: AlternativeLocations && AlternativeLocations.length > 1 -->
            <a class="more alternative-locations" href="#">more</a>
            <ul id="other-location-matches" data-bind="foreach: AlternativeLocations.slice(1).sort()" style="display: none">
                <li>&gt; Did you mean <a data-bind="html: $data, attr: { href: Edge.API.CurrentSearchResponse.SearchTerms.mutate({ Location: $data }).getUrl() }"></a>?</li>
            </ul>
        <!-- /ko -->
    <!-- /ko -->
    <!-- ko if: SearchTerms.Location && (!AlternativeLocations || AlternativeLocations.length == 0) -->
    <span class="error">We couldn't find '<span data-bind="html: SearchTerms.Location"></span>' on the map. Your search ran Worldwide.
    </span>
    <!-- /ko -->
</p>

Когда я пытаюсь связать этот шаблон с помощью Knockout, я получаю эту ошибку:

Error: Cannot find closing comment tag to match: ko if: SearchTerms.Location && AlternativeLocations && AlternativeLocations.length 

Я пробовал:

  • Модернизация нокаута с 2.2.1 до 2.3.0. Не использовать
  • Проверка структуры HTML/XML. Это хорошо!
  • Удаление <ul id="other-location-matches"...>, похоже, устраняет проблему... но мне нужно, чтобы <ul>!!

Любые идеи? Я смотрю на ошибку Knockout.js?

Ответ 1

Я столкнулся с той же проблемой, кроме тегов table.

Не работает - создает ту же проблему, что указана Mauricio

<table>
<!-- ko: foreach: { data: SomeData, as: 'item' } -->
   <tr>
      <td data-bind="text: item"></td>
   </tr>
<!-- /ko -->
</table>

Работает:

<table>
   <tbody>
   <!-- ko: foreach: { data: SomeData, as: 'item' } -->
      <tr>
         <td data-bind="text: item"></td>
      </tr>
   <!-- /ko -->
   </tbody>
</table>

Ответ 2

Краткий ответ:

HTML не допускает элемент блока внутри элемента P. Таким образом, элемент P закрыт непосредственно перед элементом UL. Ko comment открывает конец тега в элементе P и закрывающий тег снаружи. Для нокаута требуется, чтобы открытый и закрытый теги комментариев были в одном элементе.


Оригинальный ответ:

благодаря @Sash, я понял, почему тег <tbody> является обязательным.

У меня была такая же проблема с этой частью html:

<table>
    <thead>
        <th>ID
        <!-- ko if: showName() --> <th>Name <!-- /ko -->
    <tbody data-bind="foreach: data">
...

Очевидно, что это не работает по той же причине. Почему это не работает, когда я добавил </th>, пока он не работает. Мне нужно было добавить закрывающий тег перед комментарием ko. Как только я это увидел, я вспомнил SGML 101. Дополнительный тег появляется после комментария. Итак, фактическое дерево DOM выглядит так, как для моего кода:

─┬─Table
 ├─┬─THead
 │ ├─┬─Th
 │ | ├─#Data(ID)
 │ | └─#Comment(ko if:)
 │ └─┬─Th
 │   ├─#Data(Name)
 │   └─#Comment(/ko)
 └─┬─TBody
   ┊

Вы можете заметить, что тег открытия и закрытия находится на двух ветвях дерева node. Чтобы получить комментарий в правильной позиции, необходимо добавить ярлык optionnal. @michael best объясняют, почему это влияет на исходный плакат.

Ответ 3

Ну... После некоторого времени боев я, к счастью, нашел исправление. Это все еще не объясняет, почему он не разбирается в этом конкретном HTML-шаблоне (и я бы не согласился с тем, что он должен его отклонять), но, заменив <p>, охватывающий всю вещь <div>, проблема исчезнет.

Поэтому я уверен, что поведение DOM для <p> и <div> различно и, по-видимому, влияет на логику разбора шаблона нокаута.

Ответ 4

У меня была та же ошибка, вызванная самозакрывающимся тегом div, т.е.

<div /> 

изменился на

<div></div>

теперь все снова хорошо

Ответ 5

Теги <div> и <p> не должны мешать тегам комментариев <!-- ko -->. Я не могу понять, почему код, который у вас здесь есть, с тегом комментариев ko, не работает. Здесь образец jsfiddle той же структуры (за вычетом html-материала), который будет отображать/скрывать соответствующие разделы на основе значений.

Если у вас есть все подходящие теги <!-- /ko -->, у вас может быть ошибка в тэгах html. Если допустимо переключение <p> на <div>. Назовите это днем, иначе я удаляю весь ваш html и оставляю только те комментарии комментария ko. Если нет проблем, добавьте каждый элемент html назад по одному, чтобы отследить оскорбительный html. Если ничего не получается..., заново создайте ошибку в jsfiddle и обновите свой вопрос.

Ответ 6

Это также может быть вызвано, если ваш HTML плохо сформирован в целом - например, если у вас есть паразитные открывающие или закрывающие теги, которые не имеют соответствия.

В моем случае у меня был дополнительный тег <tr>. Удаление этой проблемы устранило проблему.

Ответ 7

Я знаю, что это старая тема, но на тот случай, если кто-то найдет это. Мой был намного проще

У меня было двоеточие после ко в первом комментарии:

<!-- ko: foreach:stuff --> вместо <!-- ko foreach:stuff -->