Как я могу установить состояние списка усилителей и отправить форму с этим состоянием

<!doctype html>
<html ⚡4email data-css-strict>

<head>
    <meta charset = "utf-8">
    <script async src = "https://cdn.ampproject.org/v0.js"></script>
    <script async custom-element = "amp-form" src = "https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
    <script async custom-element = "amp-list" src = "https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
    <script async custom-template = "amp-mustache" src = "https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
    <script async custom-element = "amp-bind" src = "https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
    <style amp4email-boilerplate>
        body {
            visibility: hidden
        }
    </style>
</head>

<body>
    <amp-state id = "selectedProduct">
        <script type = "application/json">
            {
                "src": "imageSrc",
                "title": "ProductName",
                "price": "400"
            }
        </script>
    </amp-state>

    <div class = "container">
        <amp-list width = "500" height = "500" layout = "responsive" src = "https://bounce.mailamp.in/similar-products" items = "products">
            <template type = "amp-mustache">
                <div class = "product-item" on = "tap:AMP.setState({
                        selectedProduct: {
                            src: {{src}},
                            title: {{title}},
                            price: {{price}}
                        }
                    })">
                    <amp-img class = "product-image" width = "100" height = "100" src = "{{src}}" alt = "Product Image"></amp-img>
                    <p>{{title}}</p>
                    <p>Price: ₹{{price}}</p>
                    <form method = "post" action-xhr = "https://bounce.mailamp.in/add-to-cart">
                        <input type = "hidden" name = "src" [value] = "selectedProduct.src">
                        <input type = "hidden" name = "title" [value] = "selectedProduct.title">
                        <input type = "hidden" name = "price" [value] = "selectedProduct.price">
                        <button type = "submit" class = "add-to-cart-button">Add to Cart</button>
                    </form>
                </div>
            </template>
        </amp-list>
    </div>
</body>
</html>

Я работаю над проектом AMP для электронной почты и пытаюсь реализовать интерактивный список продуктов, используя amp-list и amp-state. Однако у меня возникают проблемы с обновлением состояния при нажатии на продукт. Ниже приведен фрагмент кода, который я использую. Я был бы признателен за любые рекомендации о том, как правильно настроить это для динамического взаимодействия с пользователем.

В частности, я не уверен, правильно ли я использую AMP.setState для обновления состояния selectedProduct при нажатии на продукт. Любые идеи или исправления будут очень признательны!

Было бы полезно, если бы вы предоставили образец HTML с конечной точкой XHR, который поможет другим в отладке. Когда я вставляю предоставленный образец на игровую площадку, я получаю ошибку AMP CORS: Request xhr failed: The amp-access-control-allow-source-origin must be equal to the amp source origin sent in the request.​​​.

Su Zhang 21.04.2024 00:27

Это еще одна проблема: я не могу сделать запрос с игровой площадки усилителя, хотя я добавил их конечные точки, но это работает, когда я делаю запрос из Gmail. Но проблема, с которой я столкнулся, заключается в том, что состояние не меняется при нажатии на div или кнопку. Если хотите, я могу отправить вам данные, которые получаю в списке amp-list.

Adarsh Raut 21.04.2024 09:39

Я попробовал образец, который вы предоставили в своем вопросе, и в Gmail. Я получил такую ​​ошибку: Access to fetch at 'https://bounce.mailamp.in/similar-products' from source origin '[email protected]' has been blocked by AMP CORS policy: The 'AMP-Access-Control-Allow-Source-Origin' header has a value '[email protected]' that is not equal to the supplied source origin.​​​ Значит, в Gmail она тоже не работает. Чтобы облегчить отладку, нам сначала понадобится работающая конечная точка XHR, которая отвечает на правильное состояние JSON.

Su Zhang 22.04.2024 00:16

Похоже, вы жестко запрограммировали значение заголовка AMP-Access-Control-Allow-Source-Origin в [email protected] в своей конечной точке. Было бы полезно, если бы вы могли изменить свой сервер, чтобы он вместо этого отвечал значением заголовка Amp-Access-Control-Allow-Source-Origin в запросе, чтобы он работал для всех, кому нужна помощь в отладке с игровой площадки или Gmail (с источником [email protected]).

Su Zhang 22.04.2024 00:24

res.setHeader('AMP-Access-Control-Allow-Source-Origin', [ '[email protected]', '[email protected]', 'Playground.amp.dev', ]); res.setHeader('Content-Type', 'application/json'); res.status(200).json(ответ); Я делаю это. Я добавил URL-адрес игровой площадки, но все еще не могу сделать запрос с игровой площадки. Знаете ли вы, как я могу добавить его для работы с игровой площадки. Извините, но я новичок в amp-email. Также спасибо за ответ

Adarsh Raut 22.04.2024 07:37

Я использую [ссылку] (playground.amp.dev/?runtime=amp4email) эту игровую площадку. Я также проверил это с помощью инкогнито и других пользователей, оно работает. Хотя я ничего не вижу на игровой площадке Googles, запрос xhr успешен. Я также добавляю скриншот к запросу. [ссылка] (imgur.com/gallery/vlMDj0u)

Adarsh Raut 22.04.2024 08:55

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

Adarsh Raut 22.04.2024 09:10

Re: res.setHeader('AMP-Access-Control-Allow-Source-Origin', [ '[email protected]', '[email protected]', 'playground.amp.dev', ]); — Я не думаю, что вы можете установить несколько значений для этого заголовка. Вы можете использовать подстановочный знак * или отдельное значение, повторяющее значение параметра запроса __amp_source_origin (AMP CORS V1). Я только что понял, что неправильно сказал «вместо этого ответить значением заголовка Amp-Access-Control-Allow-Source-Origin в запросе» - я должен был сказать «вместо этого ответить значением параметра запроса __amp_source_origin в запросе».

Su Zhang 22.04.2024 23:19

Причина, по которой ваш XHR работает на игровой площадке AMP (playground.amp.dev/?runtime=amp4email), заключается в том, что игровая площадка AMP не выполняет надлежащие проверки AMP CORS . Когда вы создаете свои электронные письма, вам все равно необходимо исправить проблемы AMP CORS, о ​​которых я упоминал выше, иначе он не будет работать в Gmail. XHR по-прежнему не работает для меня на игровой площадке Gmail ( amp.gmail.dev), потому что игровая площадка Gmail выполняет проверки AMP CORS. По вашему другому вопросу о макете вам следует опубликовать новый вопрос.

Su Zhang 23.04.2024 00:03
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
9
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В предоставленном вами образце есть несколько ортогональных проблем:

1. В JSON, возвращаемом вашей конечной точкой, отсутствуют кавычки.

Вот как выглядит атрибут on на <div> после отрисовки шаблона Mustache:

tap:AMP.setState({
    selectedProduct: {
        src: https://bummer.in/cdn/shop/files/9000000664.2561_600x.jpg?v=1708346823,
        title: Trunks - Disco82,
        price: 599.00 
    } 
})

Это приводит к ошибке, когда вы нажимаете на элемент div, чтобы запустить выполнение AMP вызова setState:

Error: Parse error on line 3:
...          src: https://bummer.in/cdn/sho
-----------------------^
Expecting '-', '+', '*', '/', '%', '&&', '||', '<=', '<', '>=', '>', '!=', '==', '?', '.', ',', '[', '}', got ':'

Вы должны увидеть эти ошибки в консоли JS.

Значения src и title необходимо заключить в кавычки, если значения являются строковыми литералами. См. примеры по адресу https://amp.dev/documentation/comComponents/email/amp-bind#deep-merge-with-amp.setstate().

2. Между вызовом setState и отправкой формы нет зависимости от порядка.

Когда вы нажимаете «Добавить в корзину», отправка формы не ожидает выполнения оценки amp-bind скрытых элементов ввода формы после изменения состояния при нажатии внешнего div. Они происходят параллельно в неопределенном порядке. В результате обычно происходит следующее: когда вы впервые нажимаете «Добавить в корзину», форма отправляется с полями ввода, установленными на значения по умолчанию для состояния AMP (src: imageSrc и price: 400), которые вы устанавливаете внутри тега <amp-state>, как в отличие от значений, которые вы намереваетесь установить с помощью AMP.setState.

Что вы можете сделать, так это гарантировать, что форма будет отправлена ​​только после того, как произойдет setState. Это можно сделать с помощью

  1. Предоставление вашей форме идентификатора DOM
  2. Изменение кнопки на обычную кнопку, а не кнопку submit
  3. Связывание нескольких действий с одним и тем же событием и использование действия form.submit для запуска отправки формы:

https://amp.dev/documentation/guides-and-tutorials/email/learn/amp-actions-and-events#multiple-actions-for-one-event

Если вы присвоите элементу <form> идентификатор DOM form, вы можете сделать это:

<button on = "tap:AMP.setState({
              selectedProduct: {
                src: '{{src}}',
                title: '{{title}}',
                price: '{{price}}',
              }
            }), form.submit" type = "button" class = "add-to-cart-button">
  Add to Cart
</button>

Вы можете отладить состояния AMP, выполнив AMP.printState() в консоли JS в контексте фрейма AMP.

3. В конечной точке вашей формы есть проблемы с CORS.

Даже после устранения вышеуказанных проблем отправка формы не работает, поскольку она не отвечает правильными заголовками CORS:

Access to fetch at 'https://bounce.mailamp.in/add-to-cart?__amp_source_origin=https%3A%2F%2Fplayground.amp.dev' from origin 'https://playground.amp.dev' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.

Огромное Вам спасибо, Вы очень помогли. Я внес изменения, которые вы мне сказали, и добавил credentials: true, чтобы запрос xhr работал на игровой площадке, но когда я отправляю форму, в данных формы полезной нагрузки на вкладке запроса я вижу только источник и цену, я не вижу заголовок, но когда я ввожу какое-то другое свойство «имя», например ProductName, оно отображается в данных формы. Кроме того, список усилителей не отображается (amp.gmail.dev/playground), хотя запрос на получение успешен.

Adarsh Raut 23.04.2024 08:31

Атрибут name = "title" в элементе ввода формы, вероятно, удаляется с помощью DOMPurify , который используется amp-mustache. DOMPurify пытается предотвратить разрушение DOM. В данном случае title является запрещенным символом, поскольку это собственный атрибут какого-либо встроенного объекта JS, например document.title. В этом случае атрибут name не может затмить document, но DOMPurify пытается быть консервативным и дезинфицировать, даже когда это не является строго необходимым.

Su Zhang 24.04.2024 03:41

Re: «Кроме того, список amp-list не отображается на (amp.gmail.dev/playground), хотя запрос на получение успешен» — см. мои заметки под вопросом stackoverflow.com/q/78357161/1397618. Вам нужно будет исправить проблемы AMP CORS, о ​​которых я упоминал. GET XHR не работает на игровой площадке Gmail.

Su Zhang 24.04.2024 03:43

Большое спасибо за помощь. Я добавил это в бэкэнд const ampSourceOrigin = req.query.__amp_source_origin; res.set('AMP-Access-Control-Allow-Source-Origin', ampSourceOrigin); и теперь это работает. Но когда я делаю сообщение формы xhr из (playground.amp.dev/?runtime=amp4email), я получаю неопределенное значение, но получаю журнал из (amp.gmail.dev/playground). Также я добавил новый вопрос о списке amp макет, если вы будете любезны взглянуть на него: (stackoverflow.com/questions/78370357/…)

Adarsh Raut 24.04.2024 08:30

Я еще раз попробовал образец на игровой площадке AMP (playground.amp.dev/?runtime=amp4email), и он у меня работает. Теперь это также работает на игровой площадке Gmail. Не уверен, где вы увидели «неопределенное».

Su Zhang 25.04.2024 04:10

Ой, извините за этот неясный комментарий, я получаю неопределенность на внутреннем сервере, когда делаю запрос на публикацию «добавить в корзину» из (Playground.amp.dev/?runtime=amp4email ), но когда я делаю тот же запрос из ( amp.gmail.dev/playground) я получаю журнал названия продукта, цены и источника.

Adarsh Raut 26.04.2024 13:43

На игровой площадке AMP используется multipart/form-data, а на игровой площадке Gmail — application/x-www-form-urlencoded. Убедитесь, что ваш сервер может обрабатывать оба варианта взаимозаменяемо.

Su Zhang 27.04.2024 07:30

Другие вопросы по теме