Состояние ампер игнорируется до срабатывания setState () - PullRequest
1 голос
/ 04 июля 2019

Я создаю страницу усилителя, на которой должны отображаться разные URL-адреса загрузки в зависимости от страны. Я могу показать / скрыть правильный элемент <a> с помощью CSS путем добавления группы isEU в <amp-geo> config. Но мне нужна только одна ссылка на страницу с переменной href. Я пытаюсь добиться этого с помощью, но я не могу использовать <amp-state>, хотя он генерируется правильно.

Даже примеры из документации по усилителю не будут работать, пока я не нажму на <button on="tap:AMP.setState({foo: 'amp-bind'})">Say "Hello amp-bind"</button>. Затем запускаются вычисления, и на странице отображаются все значения. До этого значения не интерполировались / не рассчитывались.

Что я здесь не так делаю?

enter image description here

<!doctype html>
<html ⚡>

<head>
    <meta charset="utf-8">
    <title>TESTPAGE</title>
    <meta name="viewport"
          content="width=device-width,minimum-scale=1,initial-scale=1">
    <script async
            src="https://cdn.ampproject.org/v0.js"></script>
    <script async
            custom-element="amp-geo"
            src="https://cdn.ampproject.org/v0/amp-geo-0.1.js"></script>
    <script async
            custom-element="amp-bind"
            src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
    <style>
        [class*=-only] {
            display: none;
        }

        .amp-geo-group-isEU .eu-only {
            display: block;
        }

        body:not(.amp-geo-group-isEU) .non-eu-only {
            display: block;
        }
    </style>
</head>

<body class="amp-geo-pending">
    <amp-state id="stateTest"
               class="i-amphtml-element i-amphtml-layout-container"
               i-amphtml-layout="container"
               hidden=""
               aria-hidden="true">
        <script type="application/json">
            {
                "testInitialKey": "initial state value"
            }
        </script>
    </amp-state>
    <amp-state id="myCircle"
               class="i-amphtml-element i-amphtml-layout-container"
               i-amphtml-layout="container"
               hidden=""
               aria-hidden="true">
        <script type="application/json">
            {
                "radius": "4"
            }
        </script>
    </amp-state>
    <amp-geo layout="nodisplay">
        <script type="application/json">
            {
              "AmpBind": true,
              "ISOCountryGroups": {
                "isEU": ["at", "be", "bg", "bs", "ch", "cy", "cz", "de", "dk", "ee", "es", "fi", "fr", "gb", "gr", "hr", "hu", "ie", "is", "it", "li", "lt", "lu", "lv", "mt", "nl", "no", "pl", "pt", "ro", "se", "si", "sk"]
              }
            }
        </script>
    </amp-geo>
    <h1 [class]="ampGeo.isEU ? 'isEU' : 'nonEU'"
        [text]="'isEU: ' + (ampGeo.isEU ? 'true' : 'false').toUpperCase()"></h1>
    <h2 [text]="stateTest.testInitialKey"></h2>
    <a class="eu-only"
       [href]="'http://google.com/' + ampGeo.ISOCountry == 'cy' ? 'cyprusLink' : 'defaultLink'">LINK_CY</a>
    <a class="non-eu-only"
       href="http://google.com/?frenchLink">LINK_FR</a>
    <hr>
    <amp-bind-macro id="circleArea"
                    arguments="radius"
                    expression="3.14 * radius * radius"></amp-bind-macro>

    <div>
        The circle has an area of <span [text]="circleArea(myCircle.radius)">0</span>.
    </div>
    <hr>
    <p [text]="'Hello ' + foo">Hello World</p>
    <button on="tap:AMP.setState({foo: 'amp-bind'})">Say "Hello amp-bind"</button>
</body>

</html>

1 Ответ

2 голосов
/ 05 июля 2019

Если я правильно понимаю, проблема, с которой вы сталкиваетесь, заключается в том, что amp-bind рассчитывается только по действиям пользователя. Вы должны инициализировать начальное значение на стороне сервера. Вот как работает связывание. Идея состоит в том, чтобы обеспечить скорость страницы и не нужно запускать JavaScript при загрузке страницы.

Очень часто можно увидеть код вроде

<div class="foo" [class]="x ? 'foo' : 'bar'">

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

Однако я вижу проблему, которую это создает с AMP Geo. Должен ли сервер реплицировать эту функциональность для предварительной инициализации значения? См. Например, https://github.com/ampproject/amphtml/issues/14637. Похоже, та же проблема, с которой вы столкнулись. Вы можете добавить туда комментарий, чтобы узнать, почему вы хотели бы добавить какую-то поддержку.

...