рдпрд╣ рдкреЛрд╕реНрдЯ рдСрдЯреЛ-рдЯреНрд░реИрдХрд┐рдВрдЧ рдкрд░ рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рджреВрд╕рд░рд╛ рд╣реИ - Ember.js рдореЗрдВ рдирдИ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдгрд╛рд▓реАред рдореИрдВ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдкрд░ рднреА рдЪрд░реНрдЪрд╛ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдпрд╣ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдХреИрд╕реЗ рдкреНрд░рдХрдЯ рд╣реЛрддреА рд╣реИред
рдПрдХ рдЕрдиреБрд╡рд╛рджрдХ рд╕реЗ: рдХреНрд░рд┐рд╕ рдЧреИрд░реЗрдЯ - рд▓рд┐рдВрдХреНрдбрдЗрди рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдореНрдмрд░ рдЬреЗрдПрд╕ рдврд╛рдВрдЪреЗ рдореЗрдВ рдореБрдЦреНрдп рдпреЛрдЧрджрд╛рдирдХрд░реНрддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рдЙрдиреНрд╣реЛрдВрдиреЗ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг - рдПрдореНрдмрд░ рдСрдХреНрдЯреЗрди рдХреЛ рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд░рд┐рдп рднрд╛рдЧ рд▓рд┐рдпрд╛ ред рдЗрд╕ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдХреЛрдиреЗрд╕реНрдЯреЛрди рдореЗрдВ рд╕реЗ рдПрдХ рдСрдЯреЛрдореИрдЯрд┐рдХ рдЯреНрд░реИрдХрд┐рдВрдЧ (рдСрдЯреЛрдЯреНрд░реИрдХрд┐рдВрдЧ) рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдирдпрд╛ рд░рд┐рдПрдХреНрдЯрд┐рд╡рд┐рдЯреА рд╕рд┐рд╕реНрдЯрдо рд╣реИред рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдЙрдирдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдПрдореНрдмрд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦреА рдЧрдИ рдереА, рдпрд╣ рдЙрди рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдкрд░ рдЫреВрддреА рд╣реИ рдЬреЛ рд╕рднреА рд╡реЗрдм рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИрдВред
- рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдХреНрдпрд╛ рд╣реИ?
- рдХреНрдпрд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдЕрдЪреНрдЫрд╛ рдмрдирд╛рддрд╛ рд╣реИ? тЖР рдпрд╣ рдкреЛрд╕реНрдЯ
- рдСрдЯреЛ рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ
- рдСрдЯреЛ рдЯреНрд░реИрдХрд┐рдВрдЧ рдорд╛рдорд▓рд╛ - TrackedMap
- рдСрдЯреЛ рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдорд╛рдорд▓рд╛ - @localCopy
- рдСрдЯреЛ рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЗрд╕ - рд░рд┐рдореЛрдЯрдбрд╛рдЯрд╛
- рдСрдЯреЛ рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдорд╛рдорд▓рд╛ - рдкреНрд░рднрд╛рд╡ ()
, . , :
: , .
, , . : ?
, , . . , , . , , .
, , . , , . ! , , - ( ).
HTML
HTML . , , . HTML ( CSS) , - JavaScript!
-, HTML ? ? HTML :
<form action="/my-handling-form-page" method="post">
  <label>
    Email:
    <input type="email" />
  </label>
  <label>
    Password:
    <input type="password" />
  </label>
  <button type="submit">Log in</button>
</form>
. . тАФ , , - . , , .
тАЛтАЛ : , , , . HTML , , , тАФ (JavaScript). , HTML ? , HTML ?
HTML, input select. , , , . , , .
<style>
  input[type='checkbox'] + ul {
    display: none;
  }
  input[type='checkbox']:checked + ul {
    display: inherit;
  }
</style>
<nav>
  <ul>
    <li>
      <label for="dropdown">Dropdown</label>
      <input id="dropdown" type="checkbox" />
      <ul>
        <li>Item 1</li>
        <li>Item 2</li>
      </ul>
    </li>
  </ul>
</nav>
тАФ ┬л , CSS┬╗. . ./index.html - HTML / CSS .
HTML (, checked ). HTML- , . , , :
1. , , ,
, , HTML- . - , 10 , , .
. - . , JS .
push
push. , , . , JavaScript, .
. , , , , , - . , - <edit-word> :
customElements.define('edit-word',
  class extends HTMLElement {
    constructor() {
      super();
      const shadowRoot = this.attachShadow({mode: 'open'});
      this.form = document.createElement('form');
      this.input = document.createElement('input');
      this.span = document.createElement('span');
      shadowRoot.appendChild(this.form);
      shadowRoot.appendChild(this.span);
      this.isEditing = false;
      this.input.value = this.textContent;
      this.form.appendChild(this.input);
      this.addEventListener('click', () => {
        this.isEditing = true;
        this.updateDisplay();
      });
      this.form.addEventListener('submit', e => {
        this.isEditing = false;
        this.updateDisplay();
        e.preventDefault();
      });
      this.input.addEventListener('blur', () => {
        this.isEditing = false;
        this.updateDisplay();
      });
      this.updateDisplay()
    }
    updateDisplay() {
      if (this.isEditing) {
        this.span.style.display = 'none';
        this.form.style.display = 'inline-block';
        this.input.focus();
        this.input.setSelectionRange(0, this.input.value.length)
      } else {
        this.span.style.display = 'inline-block';
        this.form.style.display = 'none';
        this.span.textContent = this.input.value;
        this.input.style.width = this.span.clientWidth + 'px';
      }
    }
  }
);
- , . isEditing, updateDisplay span form . , . , updateDisplay .
, , isEditing . , . :
2.
isEditing , . , , тАФ .
, , .
Ember
Ember Classic push. (observers) (evert listeners) , , , . , (binding), (dependency chaining), .
fullName:
import { computed, set } from '@ember/object';
class Person {
  firstName = 'Liz';
  lastName = 'Hewell';
  @computed('firstName', 'lastName')
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}
let liz = new Person();
console.log(liz.fullName); 'Liz Hewell';
set(liz, 'firstName', 'Elizabeth');
console.log(liz.fullName); 'Elizabeth Hewell';
Classic Ember . , , , Ember . , set(), .

, (observers) , (computed) (templates) . , , , . ( ) .
Ember , , . . , - . , , . - () тАФ , , .
, , , . , , . , , .
Observables, Streams Rx.js
push, , тАФ Observable. JavaScript RxJS Angular .
, . , , , .
let count = 0;
document.addEventListener(
  'click',
  () => console.log(`Clicked ${++count} times`)
);
import { fromEvent } from 'rxjs';
import { scan } from 'rxjs/operators';
fromEvent(document, 'click')
  .pipe(scan(count => count + 1, 0))
  .subscribe(count => console.log(`Clicked ${count} times`));
Ember, тАФ , . , , .
, . , , , . , .

, (debounce), , . :
3.
, . , , . , , , , .
, , push, . (lazy) , , , Ember Classic, . , , push, , .
, , . pull.
pull
, , pull, тАФ . , , . , , , - , . , , , .
, , pull. , , . , .
, pull , . , ┬лVirtual DOM┬╗.
React VirtualDOM
Virtual DOM, , React.js . , HTML . , , , HTML, React , , HTML.
HTML-. , . -.

, React, , - . , setState API ( useState ).
class Toggle extends React.Component {
  state = { isToggleOn: true };
  handleClick = () => {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }
  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}
, ( ) .

, (consistency), , setState useState . , ( ). - React , :
4.
React , , . , React :
class Example extends React.Component {
  state = {
    value: 123;
  };
  render() {
    let part1 = <div>{this.state.value}</div>
    this.setState({ value: 456 });
    let part2 = <div>{this.state.value}</div>
    return (
      <div>
        {part1}
        {part2}
      </div>
    );
  }
}
, , part1 , part2 . , , - , . , , . React , .
, React , . API, shouldComponentUpdate() useMemo(), React .
API , тАЛтАЛ . , .
Vue:
Vue Virtual DOM, . Vue data :
const vm = new Vue({
  data: {
    a: 1
  }
});
Vue setState useState ( , API), . data , , . observables.
, :
const vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    reversedMessage() {
      return this.message.split('').reverse().join('')
    }
  }
})
reversedMessage message , message .
Vue , React, . , (memoization) , - , . push, , .
Elm
, , JavaScript. , , (autotracking) , , - .
Elm тАФ , . , ( HTML + JS). , - .
, Elm - , . , Elm .

- Elm , (memoization). , . / , .
let lastArgs;
let lastResult;
function memoizedRender(...args) {
  if (deepEqual(lastArgs, args)) {
    
    return lastResult;
  }
  lastResult = render(...args);
  lastArgs = args;
  return lastResult;
}
┬л┬╗ , , Elm .
. , HTML , React / Vue / Virtual DOM.
, , , . Elm, , - .
, Elm JavaScript . JavaScript, , . , . Redux тАФ , , .
, , тАФ , , . , .
!
, , :
- HTML / CSS
- push
- JavaScript
 тАФ Ember
 тАФ Observables / Rx.js
- pull
 тАФ React.js
 тАФ Vue.js
 тАФ Elm
:
- , , ,
- рдПрдХ рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ рдПрдХ рд░рд╛рдЬреНрдп рдХреЛ рдкрдврд╝рдиреЗ рд╕реЗ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╡реНрдпреБрддреНрдкрдиреНрди рд░рд╛рдЬреНрдп рд╣реЛрддрд╛ рд╣реИ
- рд╕рд┐рд╕реНрдЯрдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдп рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИред
- рд╕рд┐рд╕реНрдЯрдо рдкрд░рд╕реНрдкрд░ рд╡рд┐рд░реЛрдзреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд░реЛрдХрддрд╛ рд╣реИ
рдореИрдВ рдпрд╣ рджрд╛рд╡рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рдХрд┐ рдпрд╣ рд╕реВрдЪреА рд╕рдВрдкреВрд░реНрдг рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЛ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдФрд░ рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рддрд╛ рд╣реИред рдЕрдЧрд▓реА рдкреЛрд╕реНрдЯ рдореЗрдВ, рд╣рдо рдСрдЯреЛ рдЯреНрд░реИрдХрд┐рдВрдЧ рдореЗрдВ рддрд▓реНрд▓реАрди рдХрд░реЗрдВрдЧреЗ рдФрд░ рдкрддрд╛ рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдпрд╣ рдЗрди рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред