Октан действительно хорош

Я использую Ember.js с середины 2017 года, и вначале это было довольно сложно. Я задокументировал свои проблемы в этом посте« Проблемы, с которыми я сталкиваюсь (d) с Ember.js ». Прошло более двух лет с тех пор, как я опубликовал свои задачи, и со временем большинство из них исчезли, и, наоборот, я нахожу приятным развиваться с Ember.js.

В этом посте я поделюсь хорошими сторонами Ember.js, по моему скромному мнению.

  • Родные классы вместо объектной модели Ember
  • @decorators
  • @tracked и родные getter вместо свойств @computed.
  • this.property вместо get() и set()
  • Капитальный ремонт Component мира
  1. совместное размещение шаблона
  2. <AngleBracket/> синтаксис для компонента более {{handle-bar}}
  3. @named аргумент в компонентах
  4. {{this.property}} в шаблоне
  5. модификаторы, такие как on, fn, did-insert, on-destroy и т. д.

Родные классы

Благодаря поддержке собственных классов это просто JavaScript без какой-либо нагрузки на объектную модель Ember. Модель Ember Object была для меня чрезвычайно сложной, в первую очередь из-за вложенной абстракции. С введением поддержки собственных классов у меня достаточно знаний JavaScript, и мне не нужно разбираться во внутреннем устройстве, чтобы быть продуктивным.

Быстрое сравнение:

// pre Octane
export default Component.extend({
 init() {
   this._super(...arguments);
   this.set('answer', 42);
 }
});
//Octane
export default class MyComponent extends Component {
 constructor(owner, args) {
   super(owner, args);
   this.answer = 42;
 }
}

Обратите внимание на стандартное определение class, синтаксис extends, constructor, super вместо синтаксиса extend, init, this._super.

Вы можете прочитать больше о родных классах и их преимуществах в Руководстве по Ember.

@decorators

Декораторы - это функции, вызываемые для классов, элементов классов или других синтаксических форм JavaScript во время определения.

Введение @decorators еще больше упростило синтаксис.

Например:

@service('some-service')
someService;
// instead of
someService: service('some-service')
...
@action
someAction() {}
//instead of
actions {
  someAction() {}
}

@service, @action и т. Д. Не только упрощает и унифицирует использование, но и снижает когнитивную нагрузку.

Однако я не уверен, нужен ли нам декоратор @action. Я обнаружил, что функция стрелки () => {} служит той же цели, в приведенном ниже примере someArrowFunction и someAction достигают того же результата.

export default class MyComponent extends Component {
  someArrowFunction = () => {},
  @action
  someAction() {}
}

Среди этих декораторов мне больше всего нравится @tracked.

@tracked and native getter

@tracked делает очевидным, что соответствующее свойство отслеживается, и всякий раз, когда оно обновляется, изменения отражаются в пользовательском интерфейсе.

В версии до Octane это выполнялось следующим образом:

  • computed property
  • this.set()
  • set()

Было неочевидно, какое свойство наблюдается для изменений, нужно было искать this.set(), set или computed property в .js файлах.

Например:

// pre Octane
import Component from '@ember/component';
export default Component.extend({
  count: 0,
  
  suffixedValue: computed('count', function() {
    return foo + this.get('count')
  }),
  actions: {
    increase() {
      this.set('count', this.get('count') + 1);
    }, 
    decrease() {
      this.set('count', this.get('count') - 1);
    }
  }
});
// Octane
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
export default class MyComponent extends Component {
  @tracked count = 0;
  
  get suffixedValue() { 
    return 'foo' + this.count
  }
  increase = () => {
    this.count = this.count + 1;
  };
  decrease = () => {
    this.count = this.count + 1;
  };
}

Обратите внимание, что синтаксис Octane - это ванильный JavaScript без какой-либо абстракции Ember, в отличие от синтаксиса до Octane. Нет необходимости использовать set, чтобы изменения отражались в шаблоне. Используя декоратор @tracked, мы явно обеспечили реактивность и лишили будущих сопровождающих удовольствия от отслеживания происхождения реактивности.

Капитальный ремонт Component мира

В мир компонентов было внесено несколько улучшений, мне больше всего нравятся следующие:

  1. совместное размещение шаблона
  2. <AngleBracket/> синтаксис для компонента более {{handle-bar}}
  3. @named аргумент в компонентах
  4. {{this.property}} в шаблоне
  5. модификаторы, такие как on, fn, did-insert, on-destroy и т. д.

совместное размещение шаблона

Технически совместное размещение шаблонов было возможно и в дооктановую эпоху, через pod, однако это не было мейнстримом. Для меня это действительно большое дело, поскольку .js и соответствующий ему .hbs расположены вместе, гораздо легче получить доступ к аналогу, когда у меня есть соответствующие файлы, видимые в проводнике редактора. Конечно, я мог бы использовать нечеткий поиск или расширения, такие как Related Files Hopper, но ничто не сравнится с совместным размещением, по крайней мере, для меня.

Я бы хотел, чтобы даже тестовые файлы были размещены вместе, может быть, когда-нибудь.

<AngleBracket/>

Опять же, ‹AngleBracket /› поддерживался в выпуске до Octane, но стал мейнстримом с Octane.

Непосредственным преимуществом для меня является визуальная идентификация компонента с помощью помощника в файле .hbs. Раньше это было огромной проблемой.

Ой, подождите, есть и недостаток. В дни, предшествовавшие ‹AngleBracket /›, использование компонента в точности напоминало file-name, и часто было легко найти тот же file-name в кодовой базе. Однако с выходом <AngleBracket/> этот рабочий процесс для меня изменился. Я больше не могу просто искать file-name, но преобразовываю его в PascalCase (FileName), а затем ищу его. Что ж, это не препятствие, учитывая другие преимущества, которые он принес.

@ названный аргумент

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

//pre Octane
{{some-component someProperty="some-value"/}}
// Octane
<SomeComponent @someProperty="some-value"/>

Самое приятное - это то, как доступны эти @named аргументы.

// pre Octane
// not easy to identify from the usage, 
// if someProperty is a own property
// or passed as an argumemnt
this.get('someProperty'); //in .js, 
{{someProperty}} // in .hbs
// Octane
// the presense of `args` in .js and `@` in .hbs
// cleaarly identifes it to be
// passed as an argumemnt
this.args.someProperty; //in .js
{{@someProperty}} // in .hbs

{{this.property}} в шаблоне

{{this.property}} дополняет {{@namedArgument}} в доступе к соответствующим значениям в шаблонах. Глядя на синтаксис, я могу легко определить, какое свойство является собственным или которое было передано в качестве аргумента.

// pre Octane
{{somePropertyOrArgument}}
// Octane
{{this.property}} {{!-- own property --}}
{{@namedArgument}} {{!-- passed argument --}}

модификаторы типа on, fn

Я нахожу такие модификаторы, как {{on}}, {{fn}} более интуитивно понятными, чем {{action}}, {{action}} был волшебным, он искал соответствующую функцию из .js, прикреплял ее к событию click, по умолчанию позаботился о передаче параметров соответствующей функции и т. Д.

Напротив, функциональность этих модификаторов более интуитивна. Например, on предназначен для обработки событий, fn - для создания функции-оболочки.

//pre Octane
<button
  type="button"
  {{action "someAction"}}
>
<button
  type="button"
  onclick={{action "someAction" "someArgument"}}
>
// Octane
<button
  type="button"
  {{on "click" this.someAction }}
>
<button
  type="button"
  {{on "click" (fn this.someAction "someArgument"}}
>

Заключение

В последнее время было действительно приятно работать с Ember.js. Я надеюсь, что он продолжит улучшать и повышать продуктивность и счастье разработчиков.

Вот несколько ключевых вещей, которые было бы здорово иметь:

  • совместное размещение тестовых файлов с исходными файлами
  • возможность использовать настраиваемый макет каталога
  • возможность отображать компоненты ember в CodePen, JSFiddle и т. д. без создания приложения Ember
  • возможность совместного использования и использования компонентов Ember через стандартный узел узла без использования формата addon.

Большое спасибо всем участникам Ember.js за их упорный труд и за то, что они сделали его приятным для разработчиков.

И последнее, но не менее важное: я благодарен Крису Кричо, Гопалу Венкатесану за их ценную информацию и обзор. 🙏

Больше контента на plainenglish.io