Polymer и NotifyPropertyChanged в JavaScript

Есть замечательный фреймворк построения веб-приложений — Polymer. Это даже скорее не фреймворк, а реализация идеологии WebComponents в современных реалиях веб-браузеров.

Если кратко, то с его помощью можно реализовывать полноценный, удобный и быстрый (как с точки зрения производительности решения, так и скорости разработки) MVVM в JavaScript:

<dom-module id="my-component">
  <template>
    <h4>ToDo list for {{name}}:</h4>
    <ul>
      <template is="dom-repeat" items="{{model.todoitems}}">
        <li>{{item.title}}</li>
      </template>
    </ul>
    <button title="ChangeName" on-tap="ChangeName"/>
  </template>
</dom-module>
<script>
Polymer({
  is: 'my-component',
  name: 'Artur',
  model: {
    items: [
      {title: '1'}
    ]
  },
  ChangeName: function() {
    this.model.name = this.name + "_1";
  },
});
</script>

В WPF мы привыкли, что интерфейс перерисовывается автоматически, при изменении значения свойства: this.name = ‘New Name’;. Однако у многих js-mvvm-фреймворков, присвоения приходится производить с помощью магических функций: this.set(‘name’, this.name + «_1»). В Polymer успешно работает первый (удобный :)) вариант, однако при работе с массивами и вложенными объектами эти прелести заканчиваются. Код добавления новых элементов в список ToDo выглядит примерно так:

Add: function() {
  this.push('items', {title: 'another item'});
}

Редактирование же элементов в списке (например, изменение title) будет еще более ужасным:

  this.set('items.1.title', 'new title!');


Конечно от этого хочется избавится (и не только мне :)). Для этого и был создан компонент dom-bind-notifier. К сожалению, с актуальными версиями Polymer у него проблемы, и для этого его пришлось немного пропатчить, результат доступен у меня на github (также можно установить через bower install dom-bind-notifier-polymerpatch). Использование в сценарии выше крайне просто: добавляем тег

    <button title="ChangeName" on-tap="ChangeName"/>
    <dom-bind-notifier observed-object="{{model}}" path="model" deep></dom-bind-notifier>
  </template>

После этого старые-добрые присвоения отлично работают:

Add: function() {
  this.model.items.push({title: 'another item'});
},
Change: function() {
  this.model.items[1].title = 'another item';
}

Функционирует подписываясь на браузерный Object.Observe.
Полный пример использования — по ссылке. Не стесняйтесь сделать View Source :)

Успешного использования!

Опубликовать в Facebook
Опубликовать в Google Plus

11 комментариев

  1. Согласен. Собственно, здесь и написано об использовании полифиллов на данный момент.

    В будущем подобное можно будет реализовать через Proxy, который вроде бы приняли.

  2. Polymer — это всего лишь небольшая обёртка над стандартными веб-компонентами. С чего её будут забрасывать? Скорее уж Ангуляр потихоньку будет терять популярность ввиду перехода всё большего количества разработчиков на нативную реализацию того же функционала, что предоставляет Ангуляр — точно так же, как её продолжает понемногу терять jQuery.

  3. Весьма ценная фраза


    Я считаю, что Вы ошибаетесь. Давайте обсудим это. Пишите мне в PM. , или

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *