Проблема с привязкой шаблона нокаута при использовании привязки вложенного шаблона с получением сообщения: Неожиданный токен ')'

Я обновил версию нокаута и jquery до 3.5.1, но проблема ниже

Uncaught SyntaxError: невозможно обработать шаблон привязки: function(){return {name:sectionTemplate,foreach:sections,templateOptions:{deleteSection:deleteSection,openAddDocumentsDialog:openAddDocumentsDialog}} } Message: Unexpected token ')'

Есть ли проблема с библиотекой нокаута, когда мы используем вложенный шаблон.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js"></script>
    <script src="https://knockoutjs.com/downloads/jquery.tmpl.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.js"></script>
    
</head>
<body>
    
    <div data-bind="template: { name: 'items', data: breakfast, templateOptions: { header: 'Breakfast Items', message: 'Wake up to these delicious items!', class: 'breakfast' } }"></div>
     
    <script id="items" type="text/html">
        <h3>${$item.header}</h3>
        <div class="${$item.class}">
            {{each $data}}
            <p>
                <span class="name">${name}</span>
                <span class="price">${price}</span>
            </p>
            {{/each}}
        </div>
        <p><em>${$item.message}</em></p>
        <hr />
        <div data-bind="template: { name: 'items2', data: newItems, templateOptions: { header: 'New Items', message: 'Wake up to these delicious items!', class: 'breakfast'} }"></div>

    </script>
    <script id="items2" type="text/html">
        <h3>${$item.header}</h3>
        <div class="${$item.class}">
            {{each $data}}
            <p>
                <span class="name">${name}</span>
                <span class="price">${price}</span>
            </p>
            {{/each}}
        </div>
        <p><em>${$item.message}</em></p>
        <hr />


    </script>

    <script type="text/javascript">
        var viewModel = {
            breakfast: [
                { name: "toast", price: 2.50 },
                { name: "pancakes", price: 4.00 },
                { name: "eggs", price: 3.25 }],
            
            
            newItems: [
                { name: "Oats", price: 2.50 }],
        };

        ko.applyBindings(viewModel);
    </script>

</body>
</html>

Особенно ошибка возникает, когда я использую вложенный шаблон item2

Пожалуйста, помогите мне, спасибо заранее


person Riya    schedule 16.02.2021    source источник


Ответы (1)


Кажется, есть проблема с использованием templateOptions внутри шаблона. Удаление этого из шаблона элемента заставляет его работать. Чтобы обойти это, я бы предложил создать модель представления для шаблона со свойствами, которые необходимо передать, а не использовать templateOptions.

Также заметил, что для доступа к свойству newItems необходимо передать $root в первую привязку шаблона, а не свойство breakfast.

Я знаю, что это не исправление, но, надеюсь, поможет вам в отладке.

var viewModel = {

  breakfast: [{
      name: "toast",
      price: 2.50,
    },
    {
      name: "pancakes",
      price: 4.00
    },
    {
      name: "eggs",
      price: 3.25
    }
  ],


  newItems: [{
    name: "Oats",
    price: 2.50
  }],
};

ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://knockoutjs.com/downloads/jquery.tmpl.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script id="items" type="text/html">
  <h3>${$item.header}</h3>
  <div class="${$item.class}">
    {{each $data.breakfast}}
    <p>
      <span class="name">${name}</span>
      <span class="price">${price}</span>
    </p>
    {{/each}}
  </div>
  <p><em>${$item.message}</em></p>
  <hr />
  <div data-bind="template: { name: 'items2', data: newItems }"></div>
</script>

<script id="items2" type="text/html">
  <h3>${$item.header}</h3>
  <div class="${$item.class}">
    {{each $data}}
    <p>
      <span class="name">${name}</span>
      <span class="price">${price}</span>
    </p>
    {{/each}}
  </div>
  <p><em>${$item.message}</em></p>
  <hr />


</script>

<div data-bind="template: { name: 'items', data: $root, templateOptions: { header: 'Breakfast Items', message: 'Wake up to these delicious items!', class: 'breakfast' }}">
</div>

Важно

Также примечание об использовании jquery.tmpl из документации по нокауту — Примечание 6

Обратите внимание, что с декабря 2011 года jQuery.tmpl больше не находится в активной разработке. Мы рекомендуем использовать собственные шаблоны Knockout на основе DOM (т. е. привязки foreach, if, with и т. д.) вместо jQuery.tmpl или любого другого механизма шаблонов на основе строк.

Просто использование Knockoutjs и удаление jquery.tmpl

Следующий код устраняет необходимость в jquery.tmpl и просто использует синтаксис KnockoutJS в качестве альтернативного способа решения проблемы.

function templateVm(header, className, message,  data ){
  var self = this;
  self.header = header;
  self.className = className;
  self.message = message;
  self.data = data;
}


var viewModel = {
  
  breakfast: new templateVm('Breakfast Items','breakfast','Wake up to these delicious items!', [{
      name: "toast",
      price: 2.50,
    },
    {
      name: "pancakes",
      price: 4.00
    },
    {
      name: "eggs",
      price: 3.25
    }
  ]),


  newItems: new templateVm('New Items','breakfast','Wake up to these delicious items!',[{
    name: "Oats",
    price: 2.50
  }]),
};

ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script id="items" type="text/html">
  <div data-bind="template: { name: 'items2', data: breakfast }"></div>
  <div data-bind="template: { name: 'items2', data: newItems }"></div>
</script>

<script id="items2" type="text/html">
  <h3 data-bind="text: header"></h3>
  <div data-bind="class: className, template: {name: 'name-price',  foreach: data}"></div>
  <p><em data-bind="text: message"></em></p>
  <hr />
</script>

<script id="name-price" type="text/html">
    <p>
      <span class="name" data-bind="text: name"></span>
      <span class="price" data-bind="text: price"></span>
    </p>
</script>

<div data-bind="template: { name: 'items', data: $root}">
</div>

person Nathan Fisher    schedule 17.02.2021
comment
это правильный ответ, я хотел бы добавить к тому факту, что templateOptions даже не является задокументированным свойством (уже?) - person Sam; 17.02.2021
comment
Да, я быстро просмотрел архивы jquery.tmpl, но не нашел ничего, относящегося к templateOptions, что было бы полезно. - person Nathan Fisher; 17.02.2021