Подтвердить что ты не робот

Полимерные глобальные переменные

Я работаю над приложением Polymer, которое извлекает данные из RESTful API и использует его для построения интерфейса. Конкретной областью, на которой я придерживаюсь концептуально, является реализация шаблона Monostate, описанного в http://www.polymer-project.org/docs/polymer/polymer.html#global. Фактически, я могу добавить декларативные атрибуты в новый компонент, приложения-глобалы, а затем получить доступ к этому достаточно просто.

Вот ключевой вопрос: если я вытягиваю (и, возможно, повторно отправляю) данные обратно и вперед через core-ajax в API в компоненте app-globals, как я могу обеспечить, чтобы все пользователи приложений-глобалов компонент имеют одни и те же данные? Похоже, что я потерял свой моностатический подход, если я использую предложенный шаблон:

<polymer-element name="my-component">
  <template>
    <app-globals id="globals"></app-globals>
    <div id="firstname"></div>
    <div id="lastname"></div>
  </template>
  <script>
    Polymer('my-component', {
      ready: function() { this.globals = this.$.globals; }
     });
  </script>
</polymer-element>    

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

4b9b3361

Ответ 1

Каждый раз, когда вы ссылаетесь на приложения-глобалы в настраиваемом компоненте, создается новый экземпляр приложений-глобалов. Но каждый из этих экземпляров может делиться рядом свойств (считайте "статические" вары в Java или "class" vars в ObjC/Swift).

Элемент Script в элементе app-globals (или даже любой элемент Polymer) запускается только один раз - подумайте об этом как о запуске при загрузке определения компонента. Но функция Polymer в этом Script объявляет объект конфигурации со свойствами и обработчиками событий жизненного цикла, которые будут создаваться отдельно для каждого экземпляра. Приложение-глобалы Script в документе, который вы ссылаетесь (скопировано ниже UPDATE: эта версия модифицирована, как описано ниже) использует анонимное закрытие (функция, которая запускается немедленно), содержащий как общие переменные, так и функцию Polymer, объявляющую конфигурацию объект, который, в свою очередь, ссылается на общие переменные. Таким образом, каждый экземпляр этого объекта конфигурации - и, в свою очередь, каждый экземпляр приложений-глобалов - будет ссылаться на тот же набор общих переменных.

 <polymer-element name="app-globals">
  <script>
  (function() {
    var data = {
      firstName: 'John',
      lastName: 'Smith'
    }

    Polymer('app-globals', {
       ready: function() {
         this.data = data;
       }
    });
  })();
  </script>
</polymer-element>

Если один экземпляр настраиваемого компонента изменяет значение в своем экземпляре app-globals (или они внутренне изменены, как результаты вызова AJAX в вашем случае), все остальные экземпляры компонента со ссылкой на приложения-глобалы будут видеть измененные значение.

UPDATE: оригинал, скопированный из:

http://www.polymer-project.org/docs/polymer/polymer.html#global

имел недостаток, как описано в @zreptil, если вы меняете значения данных, новые значения НЕ доступны для всех других экземпляров - поскольку переменные экземпляра являются только копиями ссылочных строк. Используя объект с свойствами данных, как и в отредактированной версии выше, и только когда-либо просматривая и присваивая свойствам данных этого объекта, а не переписывая сам объект, измененные значения могут быть разделены между экземплярами.

Ответ 2

@Zreptil попросил пример выше, и поскольку мне пришлось поэкспериментировать с этим, я все-таки построил его на основе ответа Тима Стюарта и документации Полимера.

Полный пример: http://jsbin.com/figizaxihe/1/edit?html,output

У меня были проблемы с тире в id (id="global-variable"), поэтому я также добавил пример для этого.

Определение элемента

<polymer-element name="app-globals">
<script>
  (function() {
    var data = {
      firstName: 'John'
    }

    Polymer({
       ready: function() {
         this.data = data;
       }
    });
  })();

</script>
</polymer-element>

Используйте его внутри полимерного элемента

<polymer-element name="output-element" noscript>
<template>
    <app-globals id="globalvars"></app-globals>
    <h4>Output-Element</h4>
    <div>First Name: {{$.globalvars.data.firstName}}</div>
</template>
</polymer-element>

Используйте его вне полимерного элемента

<template is="auto-binding">
    <app-globals id="topglobals"></app-globals>
    <h3>First Name in Title: {{$.topglobals.data.firstName}}</h3>
</template>

Обратите внимание на тире/дефисы

  <h3>and since that took me a while to realize - dashes are not directly supported...</h3>
<template is="auto-binding">
    <!-- can use different id -->
    <app-globals id="global-variables"></app-globals>
    <div>This does not work: {{$.global-variables.data.firstName}}</div>
    <div>Correct syntax: {{$['global-variables'].data.firstName}}</div>

</template>

Полимер 1,0

См. Полимер 1.0 Глобальные переменные для решения полимера 1.0, если это интересно.