Ember.js: Рендеринг <button>в каждом цикле прерывает приложение</button>

Созданный на 17 июл. 2018  ·  43Комментарии  ·  Источник: emberjs/ember.js

В ember 3.3.0 следующий шаблон нарушает работу приложения:

{{#each buttons as |button|}}
  <button>{{button}}</button>
{{/each}}

buttons - простой массив. В консоли я вижу Uncaught Error: unreachable . Эта ошибка не возникает с другими тегами (т. Е. работает нормально) и не бывает на угле 3.2.2

Репозиторий с демонстрацией: https://github.com/GendelfLugansk/ember-rendering-bug

Bug Regression

Самый полезный комментарий

Считается ли это критическим изменением?

Да, это критическое изменение, и мы работаем над исправлением.

Меня также немного смущает RFC относительно того, разрешено ли это (и должно ли работать) или разрешено во время сборки (но ломается во время выполнения).

Текущее поведение соответствует тому, что указано в RFC (по сути, параметр блока с именем button + <button></button> в шаблоне блоков будет предполагать, что параметр блока был заданным закрывающим компонентом, и попытается отобразить его как такие), но на основе отзывов (здесь и в других вопросах) мы определили, что результат определенно является критическим изменением.

Текущий план (после обсуждения с основной командой 20.07.2018):

  • Убедитесь, что все параметры блока, которые «затеняют» обычные HTML-элементы внутри своих блоков, продолжают отображать HTML-элемент (и не предполагают, что они должны «вызывать» уступленный компонент).
  • При обнаружении этого сценария выдать сообщение об устаревании (с until: '4.0.0' )
  • Убедитесь, что линтер настроен для вновь созданных приложений Ember, которые не будут использовать запутанные имена параметров блоков (где параметр блока _ может быть_ именем элемента HTML, и этот элемент HTML вызывается в шаблоне блоков).
  • Верните эти исправления в Ember 3.3

Все 43 Комментарий

Да, подтверждено, мы столкнулись с такой же ошибкой после обновления с 3.2.2 до 3.3.0

Я несколько удивлен, что это сломалось в 3.3, но я ожидал, что это сломается в 3.4 (из-за функции вызова угловых скобок).

Я попробую покопаться, чтобы подтвердить, связано ли это ...

Переход на:

{{#each buttons as |text|}}
  <button>{{text}}</button>
{{/each}}

Должен решить проблему (если предположить, что функция вызова угловой скобки RE: верна).

@rwjblue да, изменение с button на text или btn помогает. Спасибо за объяснения.

Просто информационное сообщение: у меня была та же проблема с {{#each model, что и | img |}}. Изменение img на ie "foto" устраняет эту ошибку. Это критическое изменение (ember-source 3.2.2 => 3.3.0) где-то задокументировано?

Еще одна информация: эта проблема меня сильно обманывает, ключ в следующем: не используйте имя тега html в качестве as части each любого помощника, который что-то дает.

{{#each people as |p|}} {{!-- don't, because `p` is a html tag name --}}
  {{p.name}}
{{/each}}

{{#each people as |person|}} {{!-- this is fine --}}
  {{person.name}}
{{/each}}

Я не уверен, что это будет решающее изменение, но надеюсь, что нет.

@nightire, как я могу судить, мы можем использовать имя тега html в части as если этот тег html не используется внутри блока. Я также думаю, что это влияет не только на each но и на любой помощник блока, который что-то дает, включая наши собственные компоненты.

Подтвердите, предоставление любого параметра блока, который будет использоваться в качестве вызова угловой скобки, приведет к этой проблеме.

См. Следующие вопросы для получения дополнительной справочной информации:

Это изменение не должно было произойти в версии 3.3, и мы постараемся выяснить, почему это произошло (и исправить). Тем не менее, мы _до_ намерены, чтобы он появился как часть 3.4 (вместе с поддержкой линтинга в приложениях в качестве общего руководства).

Стоит ли ожидать, что это будет исправлено в 3.3.1?

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

Правило ember-template-lint no-shadowed-elements - отличный способ добиться этого.

Я также начал получать ошибку: недоступен с этим дополнением в 3.3 ...

https://github.com/tedconf/ember-collapsible-panel/issues

Считается ли это критическим изменением? Меня также немного смущает RFC относительно того, разрешено ли это (и должно ли работать) или разрешено во время сборки (но ломается во время выполнения).

Считается ли это критическим изменением?

Да, это критическое изменение, и мы работаем над исправлением.

Меня также немного смущает RFC относительно того, разрешено ли это (и должно ли работать) или разрешено во время сборки (но ломается во время выполнения).

Текущее поведение соответствует тому, что указано в RFC (по сути, параметр блока с именем button + <button></button> в шаблоне блоков будет предполагать, что параметр блока был заданным закрывающим компонентом, и попытается отобразить его как такие), но на основе отзывов (здесь и в других вопросах) мы определили, что результат определенно является критическим изменением.

Текущий план (после обсуждения с основной командой 20.07.2018):

  • Убедитесь, что все параметры блока, которые «затеняют» обычные HTML-элементы внутри своих блоков, продолжают отображать HTML-элемент (и не предполагают, что они должны «вызывать» уступленный компонент).
  • При обнаружении этого сценария выдать сообщение об устаревании (с until: '4.0.0' )
  • Убедитесь, что линтер настроен для вновь созданных приложений Ember, которые не будут использовать запутанные имена параметров блоков (где параметр блока _ может быть_ именем элемента HTML, и этот элемент HTML вызывается в шаблоне блоков).
  • Верните эти исправления в Ember 3.3

У меня была такая же проблема последние пару дней, пытаясь понять, что происходит:

<select>
    {{#each options as |option|}} <!--I see now the issue is I named this "option" a valid html tag -->
        <option value="{{option.id}}">{{option.name}}</option>
    {{/each}}
</select>

Переход на это также устранил проблему для:

<select>
    {{#each options as |opt|}} <!-- Renamed to "opt" -->
        <option value="{{opt.id}}">{{opt.name}}</option>
    {{/each}}
</select>

Просто выбросьте это там, чтобы получить дополнительную документацию по проблеме.

Просто выбросьте это там, чтобы получить дополнительную документацию по проблеме.

👍 спасибо за это (и извините за проблему)

@rwjblue На самом деле я не могу найти доказательства правила линта шаблона no-shadowed-elements в https://github.com/ember-template-lint/ember-template-lint/blob/master/docs/rules .md

Он существует где-нибудь еще?

@cafreeman его там нет (хотя должно быть), но правило здесь

Ах, не могу поверить, что я это пропустил. Спасибо!

Правило no-shadowed-elements не очень информативное, в конечном итоге здесь я подумал, что это правило было еще одной проблемой только с форматированием (в vscode с аддоном ember нет разницы между проблемами форматирования и ошибками, я думаю, с линтером тоже? ).

Мой вопрос в том, будет ли эта ошибка лучше в будущем? Не все будут работать с линтером, и я могу представить, как коллеги сталкиваются с этим и не знают, что происходит, когда ошибка бесполезна.

Да, я упоминал выше, что мы считаем это ошибкой и полностью хотим
сделать эргономику намного лучше (например, выдать предупреждение с полезным
сообщение вместо ошибки).

Я действительно не понимаю, почему это неоднозначно:

{{#each options as |option|}}
  <option value={{option.value}}>{{option.label}}</option>
{{/each}}

Разве компоненты угловых скобок не нужно вызывать с заглавной буквы?

Разве компоненты угловых скобок не нужно вызывать с заглавной буквы?

Нет, см. Раздел динамического вызова RFC для получения справочной информации.

Может ли кто-нибудь воспроизвести это в последней стабильной версии Ember?

@pzuraq да, я могу воспроизвести эту ошибку, используя 3.8.0

Просто чтобы все запуталось, это может случиться (это случилось со мной)
Запуск Ember 3.4

{{#each someArray as |item i|}}
  {{#if (gt i 0)}}
    {{fa-icon item.icon}}
  {{/if}}
{{/each}}

Несмотря на то, что я не использовал <i> , компонент {{fa-icon}} (из ember font awesome) создает его, и это вызывает забавную ошибку Uncaught Error: unreachable

Кроме того, это не улавливается no-shadowed-elements ember-template-lint, что затрудняет поиск и диагностику :(

Я совершенно понимаю, насколько это может сбить с толку. Внутренне ember-font-awesome изменяет выходной шаблон и заменяет вызов компонента {{fa-icon напрямую на <i> , который вызвал возникшую ошибку.

RE: это не было обнаружено no-shadowed-elements , я думаю, мы могли бы немного поработать в преобразовании AST ember-font-awesome, чтобы гарантировать, что этот конкретный сценарий не существует (в основном ошибка или автоматическая перезапись любого блока params с именем i при переносе).

@ Techn1x. @rwjblue Имя значка не может быть динамическим в fa-icon (https://github.com/FortAwesome/ember-fontawesome/blob/master/lib/ast-transform.js#L37)

У нас повсюду динамический fa-icon , он работает. Совершенно уверен, что то, что вы связали, уже имеет тлеющий / мерцание, превращающее его в строку. В противном случае мы даже не воспользуемся этим пакетом.

Вы также можете отправить объект, для которого установлены iconName и prefix .

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

Основа этого конкретного примера (с использованием i в качестве параметра блока и fa-icon во внутреннем блоке) используется в нетривиальном количестве мест по всей моей кодовой базе - в итоге я переименовал все параметр блока использует от i до index чтобы быть уверенным

Также стоит отметить, что в зависимости от версии FA, которую вы используете, будут реализованы два крутых проекта шрифтов ember. У них, вероятно, есть различия в том, что они поддерживают и т.
https://github.com/martndemus/ember-font-awesome
https://github.com/FortAwesome/ember-fontawesome

Эта проблема все еще рассматривается? кажется, что прошел почти год с тех пор, как о нем сообщили, но я столкнулся

Неперехваченная ошибка: недоступен

сообщение со следующим кодом в Ember v3.4.4 (который, как мне кажется, является текущей версией LTS).

<select>
    {{#each options as |option|}}
        <option value={{option.id}}>{{option.name}}</option>
    {{/each}}
</select>

PS С тех пор я изменил код на:

<select>
    {{#each options as |opt|}}
        <option value={{opt.id}}>{{opt.name}}</option>
    {{/each}}
</select>

что, очевидно, работает.

@Caltor последняя https://emberjs.com/releases/

@lifeart также сообщает об исправлениях 3.4 до мая 2019 года.

На данный момент 3.4 будет получать только исправления безопасности, 3.8 будет получать исправления до тех пор, пока 3.12 не будет повышен до LTS.

@rwjblue Значит, LTS на самом деле означает «мы игнорируем ошибку, пока не истечет период LTS»? Интересно. Я бы подумал, что ошибки, обнаруженные в период LTS, будут исправлены. Тем не менее, я понимаю, что это проект сообщества и т.д., и это не проблема.

@Caltor https://github.com/emberjs/ember.js/issues/16826#issuecomment -405654150 есть обходной путь для этого случая, и обходной путь довольно ясен, и он соответствует официальным правилам линтинга https://github.com/ember- шаблон-линт / тлеющий-шаблон-линт / blob / мастер / документы / правило / no-shadowed-elements.md

@Caltor - мне очень жаль, что мы не исправили это для LTS. 😩

Основные проблемы здесь заключаются в том, что его оказалось сложно исправить (я потратил на это несколько часов), и почти во всех случаях обновление во избежание конфликта делает ваш код лучше и легче для понимания, что обычно делает исправление этого конкретного ошибка с более низким приоритетом, чем другие, которые на самом деле блокируют людей.

@rwjblue Не беспокойтесь! Если линтер его подхватит, это хорошо. В любом случае, это только результат плохого кодирования.

Эта проблема также возникает, когда полученный хэш компонентов имеет то же имя, что и помощник, и линтер этого не улавливает.

<AngleTable as |t|>
  <t.header />
  {{t "unreachable"}}
</AngleTable>

@BobrImperator Я не уверен, что проблема - это то, что можно обнаружить заранее, и это всегда должно было быть неудачей, потому что локальные переменные всегда имели приоритет над глобальными. Причина, по которой мы не можем поймать это раньше времени, аналогична тому, почему вы не можете найти что-то вроде этого в JS:

function foo() {

}

function bar(foo = 'a string') {
  foo(); // Error: foo is not a function
}

Хотя разумно предположить, что это скрытая ошибка со стороны разработчика, из-за динамического характера JS мы не можем точно знать, что foo _не_ функция при передаче в bar . Если бы вместо этого мы использовали типизированный язык, возможно, мы смогли бы это сделать, но, к сожалению, я не думаю, что в настоящее время мы можем.

Я как бы плохо выразился, особо не жду, что это поймают заранее.
Но если я правильно помню, при перезаписи хелпера action произошла ошибка компиляции.
Я не помню точного синтаксиса, но он должен быть примерно таким, похожим, но с action .

<AngleTable as |action|>
  <t.header />
  {{action "unreachable"}}
</AngleTable>

это может быть другой случай, хотя

К вашему сведению, я просто потратил пару часов на отладку, пока я, наконец, не погуглил и не обнаружил эту проблему (использовал параметр и полученное имя), поэтому он все еще там на 3.15.

Что было странно, так это то, что {{log option}} сообщил о правильном значении внутри цикла, поэтому мне никогда не приходило в голову, что имя переменной могло быть проблемой

в ember 3.16.6 это все еще происходит в ios safari.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги