рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдиреЗрдЯ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░

рдореИрдВ рдЖрдкрдХреЗ рд╕рд╛рде рдПрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдореИрдВ рдХрдИ рд╡рд░реНрд╖реЛрдВ рд╕реЗ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рд╕рд╣рд┐рдд рд╡рд┐рдХрд╛рд╕рд╢реАрд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдбреЗрд╕реНрдХрдЯреЙрдк, рд╕рд░реНрд╡рд░ рдФрд░ рдореЛрдмрд╛рдЗрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдХрдИ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╕рдордп рдореМрд▓рд┐рдХ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╡реЗрдм рдкрд░ рдмрд╣реБрдд рдЦрд░рд╛рдм рддрд░реАрдХреЗ рд╕реЗ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдРрд╕реЗ рд▓реЛрдЧ рд╣реИрдВ рдЬреЛ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡реАрдПрд╕ рдХреЛрдб рд╕рдВрдкрд╛рджрдХ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд░ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ ред

рд╢реБрджреНрдз рд╡рд╛рд╕реНрддреБрдХрд▓рд╛

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЖрдкрдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░реВрдкрд░реЗрдЦрд╛ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓реЗрдЧрд╛ред рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреЗ рдЕрдВрджрд░ рд╡реНрдпреВ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдХреЗ рдкреБрдирд░реНрд▓реЗрдЦрди рдХреЗ рдмрд┐рдирд╛ рд░рд┐рдПрдХреНрдЯ, рдкреНрд░реАрдХреНрдЯ, рд╡реАрдпреВ, рдорд┐рдереНрд░рд┐рд▓ рдФрд░ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рднреАред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ Angular 1 рдкрд░ рдПрдХ рдЖрд╡реЗрджрди рд╣реИ, рддреЛ рдЖрдк рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ Angular 2+, React, Svelte, WebCompords, рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдкрдиреА рдкреНрд░рд╕реНрддреБрддрд┐ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдВрдЧреБрд▓рд░ 2+ рдкрд░ рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗ рдмрд┐рдирд╛ рдПрдХ рдЕрдзрд┐рдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдЖрд╡реЗрджрди рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЕрдВрдд рдореЗрдВ, рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ рдореЗрдВ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рднреВрд▓ рдЬрд╛рдПрдВред рдпрд╣ рдХреИрд╕рд╛ рдЬрд╛рджреВ рд╣реИ?

рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреНрдпрд╛ рд╣реИ


рдЗрд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдорд╛рд░реНрдЯрд┐рди рд░реЙрдмрд░реНрдЯ "рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░" ( рд░реЙрдмрд░реНрдЯ рд╕реА.рдорд╛рд░реНрдЯрд┐рди "рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░┬╗ ) рдХреА рдкреБрд╕реНрддрдХ рдХреЛ рдкрдврд╝рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИ ред рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЕрдВрд╢, рдЬрд┐рд╕реЗ рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рд▓реЗрдЦ рдореЗрдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред

рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдореЗрдВ рдПрдореНрдмреЗрдбреЗрдб рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░:

  1. рдврд╛рдВрдЪреЗ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░рддрд╛ред рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд┐рд╕реА рднреА рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдЙрд╕рдХреА рд╕реАрдорд╛рдУрдВ рдореЗрдВ рдирд┐рдЪреЛрдбрд╝рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдЙрдкрдХрд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
  2. Testabilityред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕, рдбреЗрдЯрд╛рдмреЗрд╕, рд╡реЗрдм рд╕рд░реНрд╡рд░, рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдмрд╛рд╣рд░реА рдШрдЯрдХ рдХреЗ рдмрд┐рдирд╛ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдирд┐рдпрдореЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
  3. UI рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░рддрд╛ред рдмрд╛рдХреА рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рдпреВрдЬрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡реЗрдм рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдирд┐рдпрдореЛрдВ рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛, рдХрдВрд╕реЛрд▓ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
  4. рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░рддрд╛ред рдЖрдк MongoDB, BigTable, CouchDB рдпрд╛ рдХреБрдЫ рдФрд░ рдХреЗ рд▓рд┐рдП Oracle рдпрд╛ SQL рд╕рд░реНрд╡рд░ рд╕реНрд╡реИрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдкрдХреЗ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдирд┐рдпрдо рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИрдВред
  5. рдХрд┐рд╕реА рднреА рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░рддрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЖрдкрдХреЗ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдирд┐рдпрдо рдмрд╕ рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВред

рдЗрд╕ рдкреБрд╕реНрддрдХ рдореЗрдВ рдХрдИ рд╡рд░реНрд╖реЛрдВ рд╕реЗ рд╡рд░реНрдгрд┐рдд рд╡рд┐рдЪрд╛рд░ рд╡рд┐рднрд┐рдиреНрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рдЬрдЯрд┐рд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЖрдзрд╛рд░ рд░рд╣реЗ рд╣реИрдВред

рдЗрд╕ рд▓рдЪреАрд▓реЗрдкрди рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕реЗрд╡рд╛, рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА, рдореЙрдбрд▓ рдкрд░рддреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд▓рд┐рдП рдПрдорд╡реАрд╕реА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЬреЛрдбрд╝рд╛ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рддреЗрдВ рдкреНрд░рд╛рдкреНрдд рдХреАрдВ:

  • рджреГрд╢реНрдп - рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдбреЗрдЯрд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рддрд░реНрдХ рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЖрднрд╛рд╕ рдХрд░рд╛рддрд╛ рд╣реИред
  • рдирд┐рдпрдВрддреНрд░рдХ - IO (рдЗрдирдкреБрдЯ-рдЖрдЙрдЯрдкреБрдЯ) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред
  • рд╕реЗрд╡рд╛ - рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдФрд░ рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рдЗрд╕рдХреЗ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред
  • рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА - рдмрд╛рд╣рд░реА рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░, рдЬреИрд╕реЗ рдХрд┐ рдбреЗрдЯрд╛рдмреЗрд╕, рдПрдкреАрдЖрдИ, рд╕реНрдерд╛рдиреАрдп рднрдВрдбрд╛рд░рдг, рдЖрджрд┐ред
  • рдореЙрдбрд▓ - рдкрд░рддреЛрдВ рдФрд░ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред

рдкреНрд░рддреНрдпреЗрдХ рдкрд░рдд рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рдкрд░ рдиреАрдЪреЗ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рд╣реИред

рд╢реБрджреНрдз рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреМрди рд╣реИ


рд╕рд░рд▓ рд╡рд┐рдХрд╛рд╕ рд╕реЗ рд▓реЗрдХрд░ рдмрдбрд╝реЗ рдПрд╕рдкреАрдП рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд╡рд┐рдХрд╛рд╕ рддрдХ рд╡реЗрдм рд╡рд┐рдХрд╛рд╕ рдПрдХ рд▓рдВрдмрд╛ рд╕рдлрд░ рддрдп рдХрд░ рдЪреБрдХрд╛ рд╣реИред рдФрд░ рдЕрдм рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрддрдиреЗ рдмрдбрд╝реЗ рд╣реЛ рдЧрдП рд╣реИрдВ рдХрд┐ рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдХреА рдорд╛рддреНрд░рд╛ рд╕рд░реНрд╡рд░, рдбреЗрд╕реНрдХрдЯреЙрдк рдФрд░ рдореЛрдмрд╛рдЗрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рддреБрд▓рдиреАрдп рдпрд╛ рдмреЗрд╣рддрд░ рд╣реЛ рдЧрдИ рд╣реИред

рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЬреЛ рдЬрдЯрд┐рд▓ рдФрд░ рдмрдбрд╝реЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рд╕рд░реНрд╡рд░ рдХреА рд▓рд╛рдЧрдд рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рд╕реЗ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдмрд┐рдирд╛ рдХреЛрдб рдФрд░ рд╕реНрдХреЗрд▓ рдХреЛ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред

рдЙрд╕реА рд╕рдордп, рдпрджрд┐ рдЖрдкрдХрд╛ рдХрд╛рд░реНрдп рдХреЗрд╡рд▓ рд▓реИрдВрдбрд┐рдВрдЧ рдкреГрд╖реНрдареЛрдВ рдХрд╛ рд▓реЗрдЖрдЙрдЯ рдФрд░ рдПрдиреАрдореЗрд╢рди рд╣реИ, рддреЛ рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ рдмрд╕ рдХрд╣реАрдВ рднреА рд╕рдореНрдорд┐рд▓рд┐рдд рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХрд╛ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдмреИрдХрдПрдВрдб рдкрд░ рд╣реИ рдФрд░ рдЖрдкрдХрд╛ рдХрд╛рд░реНрдп рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ рдФрд░ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░реЗрдВ, рдлрд┐рд░ рдЖрдк рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд▓рдЪреАрд▓реЗрдкрди рдХреЛ рдорд╣рд╕реВрд╕ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╡рд┐рд╕реНрдлреЛрдЯрдХ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рд╕реНрдкреНрд░рд┐рдВрдЧрдмреЛрд░реНрдб рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╣рд╛рдВ рд▓рд╛рдЧреВ рд╣реИ?


рд╢реБрджреНрдз рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдврд╛рдВрдЪреЗ, рдордВрдЪ рдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рд╕реЗ рдмрдВрдзрд╛ рдирд╣реАрдВ рд╣реИред рджрд╢рдХреЛрдВ рд╕реЗ, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдбреЗрд╕реНрдХрдЯреЙрдк рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рд╕рдВрджрд░реНрдн рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рд░реНрд╡рд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ Asp.Net Core, Java Spring рдФрд░ NestJS рдХреЗ рд▓рд┐рдП рдЪреМрдЦрдЯреЗ рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред IOs рдФрд░ Android рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦрддреЗ рд╕рдордп рдпрд╣ рдмрд╣реБрдд рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реИред рд▓реЗрдХрд┐рди рд╡реЗрдм рд╡рд┐рдХрд╛рд╕ рдореЗрдВ, рд╡рд╣ рдХреЛрдгреАрдп рдврд╛рдВрдЪреЗ рдореЗрдВ рдПрдХ рдмреЗрд╣рдж рдЕрд╕рдлрд▓ рд░реВрдк рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ред

рдЪреВрдВрдХрд┐ рдореИрдВ рд╕реНрд╡рдпрдВ рдХреЗрд╡рд▓ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд╣реАрдВ рд╣реВрдВ, рдмрд▓реНрдХрд┐ рдПрдХ рд╕реА # рдбреЗрд╡рд▓рдкрд░ рднреА рд╣реВрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдореИрдВ рдЗрд╕ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд╕рдВрджрд░реНрдн рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдПрд╕реНрдк.рдиреЗрдЯ рдХреЛрд░ рдХреЗ рд▓рд┐рдП рд▓реЗ рдЬрд╛рдКрдВрдЧрд╛ред

рдпрд╣рд╛рдБ рдПрдХ рд╕рд░рд▓ рдирдореВрдирд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ:

Asp.Net рдХреЛрд░ рдкрд░ рдирдореВрдирд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ
    /**
     * View
     */

    @model WebApplication1.Controllers.Profile

    <div class="text-center">
        <h1>  @Model.FirstName</h1>
    </div>

    /**
     * Controller
     */

    public class IndexController : Controller
    {
        private static int _counter = 0;
        private readonly IUserProfileService _userProfileService;

        public IndexController(IUserProfileService userProfileService)
        {
            _userProfileService = userProfileService;
        }

        public async Task<IActionResult> Index()
        {
            var profile = await this._userProfileService.GetProfile(_counter);
            return View("Index", profile);
        }

        public async Task<IActionResult> AddCounter()
        {
            _counter += 1;
            var profile = await this._userProfileService.GetProfile(_counter);
            return View("Index", profile);
        }
    }

    /**
     * Service
     */

    public interface IUserProfileService
    {
        Task<Profile> GetProfile(long id);
    }

    public class UserProfileService : IUserProfileService
    {
        private readonly IUserProfileRepository _userProfileRepository;

        public UserProfileService(IUserProfileRepository userProfileRepository)
        {
            this._userProfileRepository = userProfileRepository;
        }

        public async Task<Profile> GetProfile(long id)
        {
            return await this._userProfileRepository.GetProfile(id);
        }
    }

    /**
     * Repository
     */

    public interface IUserProfileRepository
    {
        Task<Profile> GetProfile(long id);
    }

    public class UserProfileRepository : IUserProfileRepository
    {
        private readonly DBContext _dbContext;
        public UserProfileRepository(DBContext dbContext)
        {
            this._dbContext = dbContext;
        }

        public async Task<Profile> GetProfile(long id)
        {
            return await this._dbContext
                .Set<Profile>()
                .FirstOrDefaultAsync((entity) => entity.Id.Equals(id));
        }
    }

    /**
     * Model
     */

    public class Profile
    {
        public long Id { get; set; }
        public string FirstName { get; set; }
        public string Birthdate { get; set; }
    }


рдпрджрд┐ рдЖрдк рдпрд╣ рдирд╣реАрдВ рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХреБрдЫ рднреА рдмреБрд░рд╛ рдирд╣реАрдВ рдХрд╣рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕рдХрд╛ рдкреНрд░рддреНрдпреЗрдХ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗред

Asp.Net Core рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди Java Spring, WinForms, Android рдХреЗ рд▓рд┐рдП, рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдФрд░ рд░рд┐рдПрдХреНрдЯ рд╕рдорд╛рди рд╣реЛрдВрдЧреЗ, рдХреЗрд╡рд▓ рднрд╛рд╖рд╛ рдФрд░ рджреГрд╢реНрдп рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ (рдпрджрд┐ рдХреЛрдИ рд╣реЛ) рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред

рд╡реЗрдм рдПрдкреНрд▓реАрдХреЗрд╢рди


рдПрдХрдорд╛рддреНрд░ рдврд╛рдВрдЪрд╛ рдЬрд┐рд╕рдиреЗ рд╕реНрд╡рдЪреНрдЫ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рд╡рд╣ рдерд╛ рдХреЛрдгреАрдпред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рд┐рд░реНрдл рднрдпрд╛рдирдХ рдирд┐рдХрд▓рд╛, рдХрд┐ 1 рдореЗрдВ, 2+ рдореЗрдВред

рдФрд░ рдЗрд╕рдХреЗ рдХрдИ рдХрд╛рд░рдг рд╣реИрдВ:

  1. рдХреЛрдгреАрдп рдЕрдЦрдВрдб рд░реВрдкрд░реЗрдЦрд╛ред рдФрд░ рдпрд╣ рдЙрд╕рдХреА рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдЗрд╕рдореЗрдВ рдХреБрдЫ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕реЗ рд░реЛрдЬрд╛рдирд╛ рдЪреЛрдХ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдк рдХреБрдЫ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рди рдХреЗрд╡рд▓ рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рдорд╕реНрдпрд╛рдПрдБ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдпрд╣ рд╢реБрджреНрдз рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреА рд╡рд┐рдЪрд╛рд░рдзрд╛рд░рд╛ рдХрд╛ рднреА рд╡рд┐рд░реЛрдз рдХрд░рддрд╛ рд╣реИред
  2. DI. , Javascript.
  3. . JSX. , 6, . .
  4. . Rollup ES2015 2 4 , angular 9.
  5. рдФрд░ рдХрдИ рдФрд░ рд╕рдорд╕реНрдпрд╛рдПрдВред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд░рд┐рдПрдХреНрдЯрд░ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ 5 рд╕рд╛рд▓ рдХреА рджреЗрд░реА рдХреЗ рд╕рд╛рде рдХреЛрдгреАрдп рдЖрдзреБрдирд┐рдХ рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХреА рддрдХ рд░реЛрд▓ рдХрд░рддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдЕрдиреНрдп рд░реВрдкрд░реЗрдЦрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? React, Vue, Preact, Mithril рдФрд░ рдЕрдиреНрдп рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреНрд░реЗрдЬреЗрдВрдЯреЗрд╢рди рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИрдВ рдФрд░ рдХреЛрдИ рднреА рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ ... рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╣реИ ... рдпрд╣ рдПрдХ рдкреВрд░реЗ рдореЗрдВ рд╕рдм рдХреБрдЫ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ!

рд╣рдо рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ


рд╣рдо рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рд╢реБрджреНрдз рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЬрд┐рддрдирд╛ рдХрд░реАрдм рд╣реЛ рд╕рдХреЗред рдпрд╣ рдмреАрдорд╛ рдХрдВрдкрдиреА рдХрд╛ рдПрдХ рдХрд╛рд░реНрдпрд╛рд▓рдп рд╣реИ рдЬреЛ рдЗрд╕ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓, рдмреАрдорд┐рдд рдШрдЯрдирд╛рдУрдВ, рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдмреАрдорд╛ рджрд░реЛрдВ рдФрд░ рдЙрдкрдХрд░рдгреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред

рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк

рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рд╣рд┐рд╕реНрд╕рд╛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдЖрдк рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╢реЗрд╖ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдХреЛ рдХрд╣рд╛рдВ рдФрд░ рдХреИрд╕реЗ рд░рдЦрд╛ рдЬрд╛рдПред рдЖрдЗрдП рдХрдВрдЯреНрд░реЛрд▓рд░ рд▓реЗрдпрд░ рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ, рдФрд░ рд╡реНрдпреВ рд▓реЗрдпрд░ рдХреЛ рд╕рдмрд╕реЗ рдЕрдВрдд рдореЗрдВ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред рдФрд░ рдирд┐рд░реНрдорд╛рдг рдХреЗ рджреМрд░рд╛рди, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдкрд░рдд рдкрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред

рдирд┐рдпрдВрддреНрд░рдХ рдкреИрдЯрд░реНрди


рдирд┐рдпрдВрддреНрд░рдХ - рдЖрд╡реЗрджрди рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдмрд╛рддрдЪреАрдд рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдпрд╣ рдПрдХ рд╡реЗрдм рдкреЗрдЬ рдкрд░ рдПрдХ рдмрдЯрди, рдПрдХ рдбреЗрд╕реНрдХрдЯреЙрдк рдПрдкреНрд▓рд┐рдХреЗрд╢рди, рдПрдХ рдореЛрдмрд╛рдЗрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдпрд╛ рд▓рд┐рдирдХреНрд╕ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдПрдХ рдХрдорд╛рдВрдб рджрд░реНрдЬ рдХрд░рдиреЗ, рдпрд╛ рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз, рдпрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп IO рдШрдЯрдирд╛ рдкрд░ рдПрдХ рдХреНрд▓рд┐рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдПрдХ рд╕рд╛рдл рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдореЗрдВ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдирд┐рдпрдВрддреНрд░рдХ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:

export class SimpleController { // extends React.Component<object, object>

    public todos: string[] = []; //  

    public addTodo(todo: string): void { //    
        this.todos.push(todo);
    }

    public removeTodo(index: number): void { //    
        this.todos.splice(index, 1);
    }

    // public render(): JSX.Element {...} // view injection

}

рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдПрдХ рдШрдЯрдирд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдФрд░ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд╢реБрд░реВ рдХрд░рдирд╛ рд╣реИред рдЖрджрд░реНрд╢ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрдВрдЯреНрд░реЛрд▓рд░ рд╡реНрдпреВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рд╡реЗрдм, рд░рд┐рдПрдХреНрдЯ-рдиреЗрдЯрд┐рд╡ рдпрд╛ рдЗрд▓реЗрдХреНрдЯреНрд░реЙрди рдЬреИрд╕реЗ рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдХреЗ рдмреАрдЪ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЕрдм рд╣рдорд╛рд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдВрддреНрд░рдХ рд▓рд┐рдЦреЗрдВред рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓, рдЙрдкрд▓рдмреНрдз рдЯреИрд░рд┐рдл рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕рд░реНрд╡реЛрддреНрддрдо рдЯреИрд░рд┐рдлрд╝ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реИ:

UserPageControllerред рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдирд┐рдпрдВрддреНрд░рдХ
export class UserPageControlle {

    public userProfile: any = {};
    public insuranceCases: any[] = [];
    public tariffs: any[] = [];
    public bestTariff: any = {};

    constructor() {
        this.activate();
    }

    public activate(): void {
        this.requestUserProfile();
        this.requestTariffs();
    }

    public async requestUserProfile(): Promise<void> { //  
        try {
            const response = await fetch("./api/user-profile");
            this.userProfile = await response.json();
            this.findBestTariff();
        } catch (e) {
            console.error(e);
        }
    }

    public async requestTariffs(): Promise<void> { //  
        try {
            const response = await fetch("./api/tariffs");
            this.tariffs = await response.json();
            this.findBestTariff();
        } catch (e) {
            console.error(e);
        }
    }

    public findBestTariff(): void { //    
        if (this.userProfile && this.tariffs) {
            this.bestTariff = this.tariffs.find((tarif: any) => {
                return tarif.ageFrom <= this.userProfile.age && this.userProfile.age < tarif.ageTo;
            });
        }
    }

    /**
     * ...   ,   ,
     *  ,    
     */
}


рд╣рдореЗрдВ рдПрдХ рд╕рд╛рдл рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдирд┐рдпрдорд┐рдд рдирд┐рдпрдВрддреНрд░рдХ рдорд┐рд▓рд╛, рдЕрдЧрд░ рд╣рдо рдЗрд╕реЗ React.Component рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рд▓реЗрддреЗ рд╣реИрдВ рддреЛ рд╣рдореЗрдВ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдШрдЯрдХ рдорд┐рд▓рддрд╛ рд╣реИред рдХрдИ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрд╡рд▓рдкрд░реНрд╕ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ рдХрдИ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрдорд┐рдпрд╛рдВ рд╣реИрдВред рдореБрдЦреНрдп рдПрдХ рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рддрд░реНрдХ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрдерддрд╛ рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рдЕрдиреБрд╢рдВрд╕рд┐рдд рдЯреИрд░рд┐рдл рди рдХреЗрд╡рд▓ рдЖрдкрдХреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЦрд╛рддреЗ рдореЗрдВ, рдмрд▓реНрдХрд┐ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реИрдВрдбрд┐рдВрдЧ рдкреГрд╖реНрда рдФрд░ рдХрдИ рдЕрдиреНрдп рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рднреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рддрд░реНрдХ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рд╕реЗрд╡рд╛ рдирд╛рдордХ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкрд░рдд рдореЗрдВ рд░рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рд╕реЗрд╡рд╛ рдкреИрдЯрд░реНрди


рд╕реЗрд╡рд╛ - рдЖрд╡реЗрджрди рдХреЗ рдкреВрд░реЗ рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ред рдпрджрд┐ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдХреБрдЫ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ, рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ, рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдпрд╣ рд╕реЗрд╡рд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдХрдИ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЛ рд╕рдорд╛рди рддрд░реНрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рд╡реЗ рд╕реЗрд╡рд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╕реНрд╡рдпрдВ рд╕реЗрд╡рд╛ рдкрд░рдд рдХреЛ рдирд┐рдпрдВрддреНрд░рдХ рдФрд░ рджреГрд╢реНрдп рдкрд░рдд рдФрд░ рдЙрд╕ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдирд╣реАрдВ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд┐рд╕рдореЗрдВ рд╡рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдЖрдЗрдП рдирд┐рдпрдВрддреНрд░рдХ рд╕реЗ рддрд░реНрдХ рдХреЛ рд╕реЗрд╡рд╛ рдореЗрдВ рд▓реЗ рдЬрд╛рдПрдВ рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рд╕реЗрд╡рд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:

UserPageControllerред рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рдирд┐рдпрдВрддреНрд░рдХ
import { UserProfilService } from "./UserProfilService";
import { TariffService } from "./TariffService";

export class UserPageController {

    public userProfile: any = {};
    public insuranceCases: any[] = [];
    public tariffs: any[] = [];
    public bestTariff: any = {};

    //    
    private readonly userProfilService: UserProfilService = new UserProfilService();
    private readonly tarifService: TariffService = new TariffService();

    constructor() {
        this.activate();
    }

    public activate(): void {
        this.requestUserProfile();
        this.requestTariffs();
    }

    public async requestUserProfile(): Promise<void> {
        try {
            //     
            this.userProfile = await this.userProfilService.getUserProfile();
            this.bestTariff = await this.tarifService.findBestTariff(this.userProfile);
        } catch (e) {
            console.error(e);
        }
    }

    public async requestTariffs(): Promise<void> {
        try {
            //     
            this.tariffs = await this.tarifService.getTariffs();
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * ...   ,   ,
     *  ,    
     */
}

UserProfilServiceред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛
export class UserProfilService {
    public async getUserProfile(): Promise<any> { //  
        const response = await fetch("./api/user-profile");
        return await response.json();
    }
    
    /**
     * ...        
     */
}

TariffServiceред рдЯреИрд░рд┐рдл рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛
export class TariffService {
    //  
    public async getTariffs(): Promise<any> {
        const response = await fetch("./api/tariffs");
        return await response.json();
    }

    //    
    public async findBestTariff(userProfile: any): Promise<any> {
        const tariffs = await this.getTariffs();
        return tariffs.find((tarif: any) => {
            return tarif.ageFrom <= userProfile.age &&
                userProfile.age < tarif.ageTo;
        });
    }
    
    /**
     * ...       
     */
}


рдЕрдм, рдпрджрд┐ рдХрдИ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдпрд╛ рдЯреИрд░рд┐рдл рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╡реЗ рд╕реЗрд╡рд╛рдУрдВ рд╕реЗ рдПрдХ рд╣реА рддрд░реНрдХ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ, рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдПрд╕рдУрдПрд▓рдЖрдИрдбреА рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рднреВрд▓рдирд╛ рд╣реИ рдФрд░ рдпрд╣ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдЕрдкрдиреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ рд╕реЗрд╡рд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ, рдФрд░ рдПрдХ рдЕрдиреНрдп рд╕реЗрд╡рд╛ рдЯреИрд░рд┐рдл рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред

рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдореЗрдВ рдмрджрд▓рд╛рд╡ рд╣реЛрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рднреНрд░реВрдг рд╡реЗрдмрд╕реИрдЯ рдпрд╛ рдЧреНрд░рд┐рдб рдпрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбреЗрдЯрд╛ рдХреЛ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рд╕реЗ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╡реНрдпрд╛рдкрд╛рд░рд┐рдХ рддрд░реНрдХ рдХреЛ рдбреЗрдЯрд╛ рд╕реНрд░реЛрдд рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ? рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдкрд░рдд рд╣реИред

рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдкреИрдЯрд░реНрди


рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА - рдбреЗрдЯрд╛ рд╡реЗрдпрд░рд╣рд╛рдЙрд╕ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ред рд╕реНрдЯреЛрд░реЗрдЬ рдПрдХ рд╕рд░реНрд╡рд░, рдбреЗрдЯрд╛рдмреЗрд╕, рдореЗрдореЛрд░реА, рд▓реЛрдХрд▓рд╕реНрдЯреЛрд░реЗрдЬ, рд╕реЗрд╢рдирд╕реНрдЯреЛрд░ рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рд╕реНрдЯреЛрд░реЗрдЬ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдп рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрдВрдбрд╛рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рд╕реЗрд╡рд╛ рдХреА рдкрд░рдд рдХреЛ рд░реЛрдХрдирд╛ рд╣реИред

рдЪрд▓реЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╕реЗрд╡рд╛рдУрдВ рд╕реЗ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рдирд┐рдпрдВрддреНрд░рдХ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ:
UserProfilServiceред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛
import { UserProfilRepository } from "./UserProfilRepository";

export class UserProfilService {

    private readonly userProfilRepository: UserProfilRepository =
        new UserProfilRepository();

    public async getUserProfile(): Promise<any> {
        return await this.userProfilRepository.getUserProfile();
    }
    
    /**
     * ...        
     */
}

UserProfilRepositoryред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рднрдВрдбрд╛рд░рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛
export class UserProfilRepository {
    public async getUserProfile(): Promise<any> { //  
        const response = await fetch("./api/user-profile");
        return await response.json();
    }
    
    /**
     * ...        
     */
}

TariffServiceред рдЯреИрд░рд┐рдл рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛
import { TariffRepository } from "./TariffRepository";

export class TariffService {
    
    private readonly tarifRepository: TariffRepository = new TariffRepository();

    public async getTariffs(): Promise<any> {
        return await this.tarifRepository.getTariffs();
    }

    //    
    public async findBestTariff(userProfile: any): Promise<any> {
        //    
        const tariffs = await this.tarifRepository.getTariffs();
        return tariffs.find((tarif: any) => {
            return tarif.ageFrom <= userProfile.age &&
                userProfile.age < tarif.ageTo;
        });
    }
    
    /**
     * ...       
     */
}

TariffRepositoryред рдЯреИрд░рд┐рдл рднрдВрдбрд╛рд░рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднрдВрдбрд╛рд░
export class TariffRepository {
    //  
    public async getTariffs(): Promise<any> {
        const response = await fetch("./api/tariffs");
        return await response.json();
    }

    /**
     * ...        
     */
}


рдЕрдм рдПрдХ рдмрд╛рд░ рдбреЗрдЯрд╛ рдЕрдиреБрд░реЛрдз рд▓рд┐рдЦрдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдФрд░ рдХреЛрдИ рднреА рд╕реЗрд╡рд╛ рдЗрд╕ рдЕрдиреБрд░реЛрдз рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗрдЧреАред рдмрд╛рдж рдореЗрдВ рд╣рдо рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рд╕рд░реНрд╡рд┐рд╕ рдХреЛрдб рдХреЛ рдЫреБрдП рдмрд┐рдирд╛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдХреИрд╕реЗ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдореЛрд╕рд╛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред

UserProfilService рд╕реЗрд╡рд╛ рдореЗрдВ, рдРрд╕рд╛ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рд╕реАрдзреЗ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИред рдХрд┐рд╕реА рднреА рд╕рдордп, рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдкрд░рдд рдореЗрдВ рджрд┐рдЦрд╛рдИ рдпрд╛ рдмрджрд▓ рд╕рдХрддреА рд╣реИрдВ, рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЕрдиреБрд░реЛрдз рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдпрд╛ рдбреЗрдЯрд╛ рдХреЛ рд╕рдореГрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬрдм рд╕реЗрд╡рд╛ рдкрд░рдд рдореЗрдВ рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИ, рддреЛ рдирд┐рдпрдВрддреНрд░рдХ - рд╕реЗрд╡рд╛ - рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЖрдкрдХреЗ рдХрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдпреЛрдЧрджрд╛рди рд╣реИред

рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдХрд┐ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рднрдВрдбрд╛рд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреНрдпрд╛ рд╡реЗ рд╕рд╣реА рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП рдореЙрдбрд▓реНрд╕ рд▓реЗрдпрд░ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред

рдореЙрдбрд▓: рдбреАрдЯреАрдУ, рдПрдВрдЯрд┐рдЯреАрдЬ, рд╡реНрдпреВрдореЙрдбрд▓


рдореЙрдбрд▓ - рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЖрд╡реЗрджрди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рд╡рд┐рд╡рд░рдг рдирдП рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдмрд╣реБрдд рдорджрдж рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд┐рд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдпрд╛ рдореЙрдбрд▓ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдбреЗрдЯрд╛ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред

рдЙрдкрдпреЛрдЧ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореЙрдбрд▓ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рдкреИрдЯрд░реНрди рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
  • рд╕рдВрд╕реНрдерд╛рдПрдВ - рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдЯреЗрдмрд▓ рдпрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рджреЛрд╣рд░рд╛рддреЗ рд╣реБрдП рдПрдХ рд╕рдВрд░рдЪрдирд╛ рд╣реИрдВред
  • рдбреАрдЯреАрдУ (рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдСрдмреНрдЬреЗрдХреНрдЯ) - рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рд╡рд┐рднрд┐рдиреНрди рдкрд░рддреЛрдВ рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • ViewModel - рджреГрд╢реНрдп рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдкреВрд░реНрд╡-рддреИрдпрд╛рд░ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрддреА рд╣реИред


рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЙрдбрд▓ рдФрд░ рдЕрдиреНрдп рдореЙрдбрд▓ рдЬреЛрдбрд╝реЗрдВ, рдФрд░ рдЕрдиреНрдп рдкрд░рддреЛрдВ рдХреЛ рдмрддрд╛рдПрдВ рдХрд┐ рдЕрдм рд╣рдо рдПрдХ рд╕рд╛рд░ рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдПрдХ рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ:
UserPageControllerред рдХрд┐рд╕реА рдХреЗ рдмрдЬрд╛рдп, рд╡рд░реНрдгрд┐рдд рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
import { UserProfilService } from "./UserProfilService";
import { TariffService } from "./TariffService";
import { UserProfileDto } from "./UserProfileDto";
import { TariffDto } from "./TariffDto";
import { InsuranceCaseDto } from "./InsuranceCasesDto";

export class UserPageController {

    /**
     *          
     *          .
     */
    public userProfile: UserProfileDto = new UserProfileDto();
    public insuranceCases: InsuranceCaseDto[] = [];
    public tariffs: TariffDto[] = [];
    public bestTariff: TariffDto | void = void 0;

    private readonly userProfilService: UserProfilService = new UserProfilService();
    private readonly tarifService: TariffService = new TariffService();

    constructor() {
        this.activate();
    }

    public activate(): void {
        this.requestUserProfile();
        this.requestTariffs();
    }

    public async requestUserProfile(): Promise<void> {
        try {
            this.userProfile = await this.userProfilService.getUserProfile();
            this.bestTariff = await this.tarifService.findBestTariff(this.userProfile);
        } catch (e) {
            console.error(e);
        }
    }

    public async requestTariffs(): Promise<void> {
        try {
            this.tariffs = await this.tarifService.getTariffs();
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * ...   ,   ,
     *  ,    
     */
}

UserProfilServiceред рдХрд┐рд╕реА рдХреЗ рдмрдЬрд╛рдп, рджрд┐рдП рдЧрдП рдореЙрдбрд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ
import { UserProfilRepository } from "./UserProfilRepository";
import { UserProfileDto } from "./UserProfileDto";

export class UserProfilService {

    private readonly userProfilRepository: UserProfilRepository =
        new UserProfilRepository();

    public async getUserProfile(): Promise<UserProfileDto> { //  
        return await this.userProfilRepository.getUserProfile();
    }
    
    /**
     * ...        
     */
}

TariffServiceред рдХрд┐рд╕реА рдХреЗ рдмрдЬрд╛рдп, рджрд┐рдП рдЧрдП рдореЙрдбрд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ
import { TariffRepository } from "./TariffRepository";
import { TariffDto } from "./TariffDto";
import { UserProfileDto } from "./UserProfileDto";

export class TariffService {
    
    private readonly tarifRepository: TariffRepository = new TariffRepository();

    public async getTariffs(): Promise<TariffDto[]> { //  
        return await this.tarifRepository.requestTariffs();
    }

    //  
    public async findBestTariff(userProfile: UserProfileDto): Promise<TariffDto | void> {
        const tariffs = await this.tarifRepository.requestTariffs();
        return tariffs.find((tarif: TariffDto) => {
            //  userProfile.age  userProfile.getAge()
            const age = userProfile.getAge();
            return age &&
                tarif.ageFrom <= age &&
                age < tarif.ageTo;
        });
    }
    
    /**
     * ...       
     */
}

UserProfilRepositoryред рдХрд┐рд╕реА рдХреЗ рдмрдЬрд╛рдп, рджрд┐рдП рдЧрдП рдореЙрдбрд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ
import { UserProfileDto } from "./UserProfileDto";

export class UserProfilRepository {
    public async getUserProfile(): Promise<UserProfileDto> { //  
        const response = await fetch("./api/user-profile");
        return await response.json();
    }
    
    /**
     * ...        
     */
}

TariffRepositoryред рдХрд┐рд╕реА рдХреЗ рдмрдЬрд╛рдп, рджрд┐рдП рдЧрдП рдореЙрдбрд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ
import { TariffDto } from "./TariffDto";

export class TariffRepository {
    public async requestTariffs(): Promise<TariffDto[]> { //  
        const response = await fetch("./api/tariffs");
        return await response.json();
    }

    /**
     * ...        
     */
}

UserProfileDtoред рд╣рдо рдЬрд┐рд╕ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдЙрд╕рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдореЙрдбрд▓
export class UserProfileDto { // <--      
    public firstName: string | null = null;
    public lastName: string | null = null;
    public birthdate: Date | null = null;

    public getAge(): number | null {
        if (this.birthdate) {
            const ageDifMs = Date.now() - this.birthdate.getTime();
            const ageDate = new Date(ageDifMs);
            return Math.abs(ageDate.getUTCFullYear() - 1970);
        }
        return null;
    }

    public getFullname(): string | null {
        return [
            this.firstName ?? "",
            this.lastName ?? ""
        ]
            .join(" ")
            .trim() || null;
    }

}

TariffDtoред рд╣рдо рдЬрд┐рд╕ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдЙрд╕рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдореЙрдбрд▓
export class TariffDto {
    public ageFrom: number = 0;
    public ageTo: number = 0;
    public price: number = 0;
}


рдЕрдм рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╣реИрдВ, рд╣рдореЗрдВ рдкрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореЙрдбрд▓ рдХреЗ рд╡рд░реНрдгрди рдХреЗ рдХрд╛рд░рдг, рд╣рдореЗрдВ рдЕрдкрдиреА рд╕реЗрд╡рд╛ рдореЗрдВ рддреНрд░реБрдЯрд┐ рдорд┐рд▓реАред рд╕реЗрд╡рд╛ рддрд░реНрдХ рдореЗрдВ, userProfile.age рдЧреБрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдиреНрдо рддрд┐рдерд┐ рд╣реИред рдФрд░ рдЖрдпреБ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ userProfile.getAge () рдореЙрдбрд▓ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИред рдпрджрд┐ рд╣рдо рдореЙрдбрд▓ рд╕реЗ рдЙрди рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╡рд░реНрддрдорд╛рди рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдПрдХ рдЕрдкрд╡рд╛рдж рдорд┐рд▓реЗрдЧрд╛ред рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ response.json () рдФрд░ JSON.parse () рддрд░реАрдХреЗрдпрд╣ рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдХреЛ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ JSON рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рд╕реЗ рдЬреБрдбрд╝рд╛ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдк рдХрдорд╛рдВрдб userProfile Instof UserProfileDto рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдкрдХреЛ рдПрдХ рдЧрд▓рдд рд╡рд┐рд╡рд░рдг рдорд┐рд▓рддрд╛ рд╣реИред рдмрд╛рд╣рд░реА рд╕реНрд░реЛрдд рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЛ рд╡рд░реНрдгрд┐рдд рдореЙрдбрд▓ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдбреЗрдЯрд╛ рдбрд┐рд╕реЗрд░рд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреА рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИред

рдбреЗрдЯрд╛ рдбрд┐рд╕реЗрд░рд┐рдПрд▓рд╛рдЗрдЬрд╝реЗрд╢рди


рджреЗрд╢реАрдХрд░рдг - рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдЕрдиреБрдХреНрд░рдо рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдмрд╣рд╛рд▓ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ред рдпрджрд┐ рдбреЗрдЯрд╛ рдореЗрдВ рдореЙрдбрд▓ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕реЗ рдЕрдирджреЗрдЦрд╛ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрджрд┐ рдбреЗрдЯрд╛ рдореЗрдВ рдРрд╕реА рдЬрд╛рдирдХрд╛рд░реА рд╣реИ рдЬреЛ рдореЙрдбрд▓ рдХреЗ рд╡рд┐рд╡рд░рдг рдХрд╛ рд╡рд┐рд░реЛрдзрд╛рднрд╛рд╕ рдХрд░рддреА рд╣реИ, рддреЛ рдПрдХ рдбреАрд░рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреАред

рдФрд░ рдпрд╣рд╛рдВ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ ES2015 рдХреЛ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд░рддреЗ рд╕рдордп рдФрд░ рдХреНрд▓рд╛рд╕ рдХреЗ рдХреАрд╡рд░реНрдб рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рджреМрд░рд╛рди , рд╡реЗ рдбреАрд╕реЗрд░рд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдЬреЛрдбрд╝рдирд╛ рднреВрд▓ рдЧрдП ... рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╕рднреА рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИ, ES2015 рдореЗрдВ рд╡реЗ рдмрд╕ рднреВрд▓ рдЧрдП ...

рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ deserialization рдХреЗ рд▓рд┐рдП TS-Serializable рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓рд┐рдЦрд╛ , рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд▓реЗрдЦред рдЗрд╕ рд▓рд┐рдВрдХ рдкрд░ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред рдЬрд┐рд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдЦреЛрдИ рд╣реБрдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╣реИред

рдореЙрдбрд▓ рдореЗрдВ deserialization рд╕рдорд░реНрдерди рдЬреЛрдбрд╝реЗрдВ рдФрд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рд▓рд┐рдП рдЦреБрдж deserialization:
TariffRepositoryред рдПрдХ deserialization рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬреЛрдбрд╝реЗрдВ
import { UserProfileDto } from "./UserProfileDto";

export class UserProfilRepository {
    public async getUserProfile(): Promise<UserProfileDto> {
        const response = await fetch("./api/user-profile");
        const object = await response.json();
        return new UserProfileDto().fromJSON(object); //  
    }
    
    /**
     * ...        
     */
}

TariffRepositoryред рдПрдХ deserialization рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬреЛрдбрд╝реЗрдВ
import { TariffDto } from "./TariffDto";

export class TariffRepository {
    public async requestTariffs(): Promise<TariffDto[]> { //  
        const response = await fetch("./api/tariffs");
        const objects: object[] = await response.json();
        return objects.map((object: object) => {
            return new TariffDto().fromJSON(object); //  
        });
    }

    /**
     * ...        
     */
}

ProfileDtoред Deserialization рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рдирд╛
import { Serializable, jsonProperty } from "ts-serializable";

export class UserProfileDto extends Serializable { // <--    

    @jsonProperty(String, null) // <--  
    public firstName: string | null = null;

    @jsonProperty(String, null) // <--  
    public lastName: string | null = null;

    @jsonProperty(Date, null) // <--  
    public birthdate: Date | null = null;

    public getAge(): number | null {
        if (this.birthdate) {
            const ageDifMs = Date.now() - this.birthdate.getTime();
            const ageDate = new Date(ageDifMs);
            return Math.abs(ageDate.getUTCFullYear() - 1970);
        }
        return null;
    }

    public getFullname(): string | null {
        return [
            this.firstName ?? "",
            this.lastName ?? ""
        ]
            .join(" ")
            .trim() || null;
    }

}

TariffDtoред Deserialization рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рдирд╛
import { Serializable, jsonProperty } from "ts-serializable";

export class TariffDto extends Serializable { // <--    

    @jsonProperty(Number, null) // <--  
    public ageFrom: number = 0;

    @jsonProperty(Number, null) // <--  
    public ageTo: number = 0;

    @jsonProperty(Number, null) // <--  
    public price: number = 0;

}


рдЕрдм рдЖрд╡реЗрджрди рдХреА рд╕рднреА рдкрд░рддреЛрдВ рдореЗрдВ, рдЖрдк рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЙрди рдореЙрдбрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬрд┐рдирдХреА рд╣рдо рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВред рджреГрд╢реНрдп, рдирд┐рдпрдВрддреНрд░рдХ рдФрд░ рдЕрдиреНрдп рдкрд░рддреЛрдВ рдореЗрдВ, рдЖрдк рд╡рд░реНрдгрд┐рдд рдореЙрдбрд▓ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдХреНрдпрд╛ рдХреЗ рд▓рд┐рдП Serializable рдФрд░ jsonProperty рд╣реИрдВ?
Serializable тАФ Ecmascript Typescript. jsonProperty , Typescript uniontypes. .

рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓рдЧрднрдЧ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЪреБрдХрд╛ рдЖрд╡реЗрджрди рд╣реИред рдпрд╣ рдирд┐рдпрдВрддреНрд░рдХ, рд╕реЗрд╡рд╛ рдФрд░ рдореЙрдбрд▓ рдкрд░рддреЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рддрд░реНрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрдиреБрд░реЛрдз рдХреЗ рдмрдЬрд╛рдп рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдкрд░рдд рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рдХреЛ рдЫреВрдиреЗ рдХреЗ рдмрд┐рдирд╛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдХреИрд╕реЗ рдмрджрд▓рдирд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдбрд┐рдкреЗрдВрдбреЗрдВрд╕реА рдЗрдВрдЬреЗрдХреНрд╢рди рдкреИрдЯрд░реНрди рд╣реИред

рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди - рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди


рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди - рдирд┐рдпрдВрддреНрд░рдгрдХрд░реНрддрд╛, рд╕реЗрд╡рд╛, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдкрд░рддреЛрдВ рдореЗрдВ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдЗрди рдкрд░рддреЛрдВ рдХреЗ рдмрд╛рд╣рд░ рдЗрди рдирд┐рд░реНрднрд░рддрд╛рдУрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ, рдирд┐рдпрдВрддреНрд░рдХ рдкрд░рдд рд╕реЗрд╡рд╛ рдкрд░рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдкрд░рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рд╡рд░реНрддрдорд╛рди рд░реВрдк рдореЗрдВ, рдкрд░рддреЗрдВ рд╕реНрд╡рдпрдВ рддрд╛рддреНрдХрд╛рд▓рд┐рдХрддрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдкрдиреА рдирд┐рд░реНрднрд░рддрд╛ рдХрд╛ рдХрд╛рд░рдг рдмрдирддреА рд╣реИрдВред рдФрд░ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд░рдд рдХреЛ рдмрд╛рд╣рд░ рд╕реЗ рдЗрд╕ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрднрд░рддрд╛ рд╕реЗ рдЧреБрдЬрд░ рд░рд╣рд╛ рд╣реИред

рддрдм рд╕рднреА рдЖрд╢реНрд░рд┐рддреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рдмрдирд╛рдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реЛрдЧрд╛:
var programm = new IndexPageController(new ProfileService(new ProfileRepository()));

рд╕рд╣рдордд - рдпрд╣ рднрдпрд╛рдирдХ рд▓рдЧ рд░рд╣рд╛ рд╣реИред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдпрд╣ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдХреЗрд╡рд▓ рджреЛ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВ, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рднрдпрд╛рдирдХ рд▓рдЧ рд░рд╣рд╛ рд╣реИред рдЙрди рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд╣рдирд╛ рд╣реИ рдЬрд┐рдирдореЗрдВ рд╕реИрдХрдбрд╝реЛрдВ рдФрд░ рд╣рдЬрд╛рд░реЛрдВ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВред

рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЙрдкрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕реЗ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рд╣рдо рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Asp.Net Core рдЕрдиреНрдп рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдХреЗ рдЕрдиреБрднрд╡ рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╡рд╣рд╛рдВ рдирд┐рд░реНрднрд░рддрд╛ рдХрд╛ рдкрдВрдЬреАрдХрд░рдг рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЪрд░рдг рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
DI.register(IProfileService,ProfileService);

рдФрд░ рдлрд┐рд░, рдирд┐рдпрдВрддреНрд░рдХ рдмрдирд╛рддреЗ рд╕рдордп, рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реНрд╡рдпрдВ рдЗрд╕ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдмрдирд╛рдПрдЧрд╛ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░реЗрдЧрд╛ред

рд▓реЗрдХрд┐рди рддреАрди рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ:
  1. рдЬрдм рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдХреЛрдИ рдирд┐рд╢рд╛рди рдирд╣реАрдВ рдмрдЪрд╛ рд╣реИред
  2. рдХреНрд▓рд╛рд╕рд┐рдХ рдбреАрдЖрдИ рдореЗрдВ рдЬреЛ рдХреБрдЫ рднреА рдЧрд┐рд░рддрд╛ рдерд╛ рд╡рд╣ рд╣рдореЗрд╢рд╛ рдХреЗ рд▓рд┐рдП рдЗрд╕рдореЗрдВ рд░рд╣рддрд╛ рд╣реИред рд░рд┐рдлреИрдХреНрдЯрд░рд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рдЗрд╕реЗ рд╕рд╛рдл рдХрд░рдирд╛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдФрд░ рдПрдХ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ, рдЖрдкрдХреЛ рд╣рд░ рдмрд╛рдЗрдЯ рдХреЛ рд╕рд╣реЗрдЬрдирд╛ рд╣реЛрдЧрд╛ред
  3. рд▓рдЧрднрдЧ рд╕рднреА рджреГрд╢реНрдп рдкреБрд╕реНрддрдХрд╛рд▓рдп DI рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рдбрд┐рдЬрд╛рдЗрдирд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╡реНрдпрд╕реНрдд рд╣реИрдВред


рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ, DI рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдХреЛрдгреАрдп 2+ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреЛрдгреАрдп 1 рдореЗрдВ, рдЬрдм рдПрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рдмрдЬрд╛рдп рдирд┐рд░реНрднрд░рддрд╛ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реБрдП, рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЗрдирд╡рд░реНрд╕реАрдлреИрдЬ рдореЗрдВ, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдмрдЬрд╛рдп рдкреНрд░рддреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдпрд╣ рд╕рдм рдЗрддрдиреА рдмреБрд░реА рддрд░рд╣ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЗрди рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдХреЗ рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рдирдпрд╛ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред

рддреАрдиреЛрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореЗрд░реЗ рдЕрдкрдиреЗ рдбрд┐ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдЗрд╕рдХреЗ рд╕рдорд╛рдзрд╛рди рдиреЗ рдореБрдЭреЗ рдЬрд╛рд╡рд╛ рд╕реНрдкреНрд░рд┐рдВрдЧ рдлреНрд░реЗрдорд╡рд░реНрдХ рдФрд░ рдЗрд╕рдХреЗ рдСрдЯреЛрд╡рд╛рд░реНрдб рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдЦреЛрдЬрдиреЗ рдореЗрдВ рдорджрдж рдХреАред рдпрд╣ рдбреАрдЖрдИ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рд▓рд┐рдВрдХ рдкрд░ рд▓реЗрдЦ , рдФрд░ рдЧрд┐рдЯрд╣рдм рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдореЗрдВ рдкрд░рд┐рдгрд╛рдореА DI рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред

рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рдбрд╛рд▓реЗрдВ


рд╕рднреА рдкрд░рддреЛрдВ рдкрд░ DI рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдбреЗрдХреЛрд░реЗрдЯрд░ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗ, рдЬрд┐рд╕рд╕реЗ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд░реНрднрд░рддрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдореЗрдЯрд╛-рдЬрд╛рдирдХрд╛рд░реА рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рд╣реЛрдЧрд╛ред рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рдЖрд╢реНрд░рд┐рддреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд╣рдо рдСрдЯреЛрдмрд╛рдпрд░реНрдб рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рд▓рдЯрдХрд╛рдПрдВрдЧреЗред рдФрд░ рдЙрд╕ рд╕реНрдерд╛рди рдкрд░ рдЬрд╣рд╛рдВ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

UserProfilRepository рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рд▓рд┐рдП, рд╕рдорд╛рди рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдмрдирд╛рдПрдВ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрдиреБрд░реЛрдз рдХреЗ рдмрдЬрд╛рдп рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рдеред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдорд┐рд▓рддреЗ рд╣реИрдВ:
Main.ts. рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд╛рди
import { override } from "first-di";
import { UserProfilRepository } from "./UserProfilRepository";
import { MockUserProfilRepository } from "./MockUserProfilRepository";

if (process.env.NODE_ENV === "test") {
    //         
    override(UserProfilRepository, MockUserProfilRepository);
}

UserPageControllerред рдСрдЯреЛрдмрд╛рдпрд░реНрдб рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд┐рд░реНрднрд░рддрд╛
import { UserProfilService } from "./UserProfilService";
import { TariffService } from "./TariffService";
import { UserProfileDto } from "./UserProfileDto";
import { TariffDto } from "./TariffDto";
import { InsuranceCaseDto } from "./InsuranceCasesDto";
import { autowired } from "first-di";

export class UserPageController {

    public userProfile: UserProfileDto = new UserProfileDto();
    public insuranceCases: InsuranceCaseDto[] = [];
    public tariffs: TariffDto[] = [];
    public bestTariff: TariffDto | void = void 0;

    @autowired() //  
    private readonly userProfilService!: UserProfilService;

    @autowired() //  
    private readonly tarifService!: TariffService;

    constructor() {
        //     , ..  
        this.activate();
    }

    public activate(): void {
        this.requestUserProfile();
        this.requestTariffs();
    }

    public async requestUserProfile(): Promise<void> {
        try {
            this.userProfile = await this.userProfilService.getUserProfile();
            this.bestTariff = await this.tarifService.findBestTariff(this.userProfile);
        } catch (e) {
            console.error(e);
        }
    }

    public async requestTariffs(): Promise<void> {
        try {
            this.tariffs = await this.tarifService.getTariffs();
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * ...   ,   ,
     *  ,    
     */
}

UserProfilServiceред рдкреЗрд╢ рд╣реИ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдФрд░ рдирд┐рд░реНрднрд░рддрд╛ рдкреАрдврд╝реА
import { UserProfilRepository } from "./UserProfilRepository";
import { UserProfileDto } from "./UserProfileDto";
import { reflection } from "first-di";

@reflection //  typescript  
export class UserProfilService {

    private readonly userProfilRepository: UserProfilRepository;

    constructor(userProfilRepository: UserProfilRepository) {
        //    
        this.userProfilRepository = userProfilRepository;
    }

    public async getUserProfile(): Promise<UserProfileDto> {
        return await this.userProfilRepository.getUserProfile();
    }

    /**
     * ...        
     */
}

TariffServiceред рдкреЗрд╢ рд╣реИ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдФрд░ рдирд┐рд░реНрднрд░рддрд╛ рдкреАрдврд╝реА
import { TariffRepository } from "./TariffRepository";
import { TariffDto } from "./TariffDto";
import { UserProfileDto } from "./UserProfileDto";
import { reflection } from "first-di";

@reflection //  typescript  
export class TariffService {

    private readonly tarifRepository: TariffRepository;

    constructor(tarifRepository: TariffRepository) {
        //    
        this.tarifRepository = tarifRepository;
    }

    public async getTariffs(): Promise<TariffDto[]> {
        return await this.tarifRepository.requestTariffs();
    }

    public async findBestTariff(userProfile: UserProfileDto): Promise<TariffDto | void> {
        const tariffs = await this.tarifRepository.requestTariffs();
        return tariffs.find((tarif: TariffDto) => {
            const age = userProfile.getAge();
            return age &&
                tarif.ageFrom <= age &&
                age < tarif.ageTo;
        });
    }

    /**
     * ...       
     */
}


UserProfilRepositoryред рдкреЗрд╢ рд╣реИ рдкрд░рд╛рд╡рд░реНрддрди рдкреАрдврд╝реА
import { UserProfileDto } from "./UserProfileDto";
import { reflection } from "first-di";

@reflection //  typescript  
export class UserProfilRepository {
    public async getUserProfile(): Promise<UserProfileDto> {
        const response = await fetch("./api/user-profile");
        const object = await response.json();
        return new UserProfileDto().fromJSON(object);
    }

    /**
     * ...        
     */
}

MockUserProfilRepositoryред рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдирдпрд╛ рднрдВрдбрд╛рд░
import { UserProfileDto } from "./UserProfileDto";
import { reflection } from "first-di";

@reflection //  typescript  
export class MockUserProfilRepository { //   
    public async getUserProfile(): Promise<UserProfileDto> {
        const profile = new UserProfileDto();
        profile.firstName = "";
        profile.lastName = "";
        profile.birthdate = new Date(Date.now() - 1.5e12);
        return Promise.resolve(profile); //   
    }

    /**
     * ...        
     */
}

TariffRepositoryред рдкреЗрд╢ рд╣реИ рдкрд░рд╛рд╡рд░реНрддрди рдкреАрдврд╝реА
import { TariffDto } from "./TariffDto";
import { reflection } from "first-di";

@reflection //  typescript  
export class TariffRepository {
    public async requestTariffs(): Promise<TariffDto[]> {
        const response = await fetch("./api/tariffs");
        const objects: object[] = await response.json();
        return objects.map((object: object) => {
            return new TariffDto().fromJSON(object);
        });
    }

    /**
     * ...        
     */
}


рдЕрдм, рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдХрд╣реАрдВ рднреА рдХрд┐рд╕реА рднреА рддрд░реНрдХ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрджрд▓рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИред рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рдмрдЬрд╛рдп, рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ, рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХрд╣реАрдВ рднреА рдорд┐рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдХрд┐рд╕реА рд╕реЗрд╡рд╛ рдореЗрдВ рддрд░реНрдХ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдкреБрд░рд╛рдиреА рд╕реЗрд╡рд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирдпрд╛ рд╣реИред рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдП / рдмреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдХрд░реЗрдВ, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝-рдЖрдзрд╛рд░рд┐рдд рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд╕рдВрдмрдВрдзрдкрд░рдХ рдореЗрдВ рдмрджрд▓реЗрдВ, рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╡реЗрдм рд╕реЙрдХреЗрдЯ рдореЗрдВ рдмрджрд▓реЗрдВред рдФрд░ рдпрд╣ рд╕рдм рд╕рдорд╛рдзрд╛рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд╛рд╕ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рдмрд┐рдирд╛ред

рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦрдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рд╡реНрдпреВ рд▓реЗрдпрд░ рд╣реИред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреГрд╢реНрдп


рд╡реНрдпреВ рд▓реЗрдпрд░ рдЙрд╕ рдбреЗрдЯрд╛ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ рдЬреЛ рдирд┐рдпрдВрддреНрд░рдХ рдкрд░рдд рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдирд┐рд╣рд┐рдд рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рд░рд┐рдПрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд╕реНрдерд╛рди рдкрд░ рдХреЛрдИ рдЕрдиреНрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░реАрдХреНрдЯ, рд╕реНрд╡реЗрд▓реНрдЯреЗ, рд╡реНрдпреВ, рдорд┐рдереНрд░рд┐рд▓, рд╡реЗрдмрдХрдВрдкреЛрдиреЗрдВрдЯ рдпрд╛ рдХреЛрдИ рдЕрдиреНрдпред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ React.Component рд╕реЗ рд╣рдорд╛рд░реЗ рдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЛ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░реЗрдВ, рдФрд░ рд╡реНрдпреВ рдХреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЗ рд╕рд╛рде рдПрдХ рд░реЗрдВрдбрд░ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ:

Main.ts. рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ
import { override } from "first-di";
import { UserProfilRepository } from "./UserProfilRepository";
import { MockUserProfilRepository } from "./MockUserProfilRepository";
import { UserPageController } from "./UserPageController";
import React from "react";
import { render } from "react-dom";

if (process.env.NODE_ENV === "test") {
    //         
    override(UserProfilRepository, MockUserProfilRepository);
}

render(React.createElement(UserPageController), document.body);

UserPageControllerред React.Component рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рд░реЗрдВрдбрд░ рдореЗрдердб рдЬреЛрдбрд╝рддрд╛ рд╣реИ
import { UserProfilService } from "./UserProfilService";
import { TariffService } from "./TariffService";
import { UserProfileDto } from "./UserProfileDto";
import { TariffDto } from "./TariffDto";
import { InsuranceCaseDto } from "./InsuranceCasesDto";
import { autowired } from "first-di";
import React from "react";

//    React.Component
export class UserPageController extends React.Component<object, object> {

    public userProfile: UserProfileDto = new UserProfileDto();
    public insuranceCases: InsuranceCaseDto[] = [];
    public tariffs: TariffDto[] = [];
    public bestTariff: TariffDto | void = void 0;

    @autowired()
    private readonly userProfilService!: UserProfilService;

    @autowired()
    private readonly tarifService!: TariffService;

    //   
    constructor(props: object, context: object) {
        super(props, context);
    }

    //     
    public componentDidMount(): void {
        this.activate();
    }

    public activate(): void {
        this.requestUserProfile();
        this.requestTariffs();
    }

    public async requestUserProfile(): Promise<void> {
        try {
            this.userProfile = await this.userProfilService.getUserProfile();
            this.bestTariff = await this.tarifService.findBestTariff(this.userProfile);
            this.forceUpdate(); //  view   
        } catch (e) {
            console.error(e);
        }
    }

    public async requestTariffs(): Promise<void> {
        try {
            this.tariffs = await this.tarifService.getTariffs();
            this.forceUpdate(); //  view   
        } catch (e) {
            console.error(e);
        }
    }

    //   view
    public render(): JSX.Element {
        return (
            <>
                <div className="user">
                    <div className="user-name">
                         : {this.userProfile.getFullname()}
                    </div>
                    <div className="user-age">
                        : {this.userProfile.getAge()}
                    </div>
                </div>
                <div className="tarifs">
                    {/*    */}
                </div>
            </>
        );
    }

    /**
     * ...   ,   ,
     *  ,    
     */
}


рдХреЗрд╡рд▓ рджреЛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдФрд░ рдПрдХ рдкреНрд░рд╕реНрддреБрддрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдЬреЛрдбрд╝рдХрд░, рд╣рдорд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рдХ рдХрд╛рд░реНрдп рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛ред

рдХреНрдпреЛрдВ рд╕реЗрдЯрд╕реНрдЯреИрдЯ рдХреЗ рдмрдЬрд╛рдп рдлреЛрд░реНрд╕рдЕрдкрдбреЗрдЯ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ?
forceUpdate , setState. setState, Redux, mobX ., . React Preact forceUpdate, ChangeDetectorRef.detectChanges(), Mithril redraw . Observable , MobX Angular, . .

рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рднреА, рдпрд╣ рдирд┐рдХрд▓рд╛ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рдЬреАрд╡рди рдЪрдХреНрд░, рджреГрд╢реНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдФрд░ рдЕрдорд╛рдиреНрдп рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рд╕рд╛рде рд░рд┐рдПрдХреНрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдмрдВрдзреЗ рд╣реИрдВ, рдЬреЛ рд╕реНрд╡рдЪреНрдЫ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рд╡рд┐рд░реЛрдз рдХрд░рддрд╛ рд╣реИред рдФрд░ рддрд░реНрдХ рдФрд░ рд▓реЗрдЖрдЙрдЯ рдПрдХ рд╣реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╣реИрдВ, рдЬреЛ рдЯрд╛рдЗрдкреНрдЯрд░ рдФрд░ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд╕рдорд╛рдирд╛рдВрддрд░ рдХрд╛рдо рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░рддрд╛ рд╣реИред

рдирд┐рдпрдВрддреНрд░рдХ рдФрд░ рджреГрд╢реНрдп рдХрд╛ рдкреГрдердХреНрдХрд░рдг


рджреЛрдиреЛрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рджреГрд╢реНрдп рдкрд░рдд рдХреЛ рдПрдХ рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдЖрдзрд╛рд░ рдШрдЯрдХ рдмрдирд╛рддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рд╕реНрддреБрддрд┐ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рд╣рдорд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдЕрдореВрд░реНрдд рдХрд░реЗрдЧрд╛ред рдЙрд╕реА рд╕рдордп, рд╣рдо рдЙрди рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдШрдЯрдХ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВред

рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рд╡рд░реНрддрди рдорд┐рд▓рддреЗ рд╣реИрдВ:
UserPageViewред рд╡реЗ рдПрдХ рдЕрд▓рдЧ рдлрд╛рдЗрд▓ рдкрд░ рд▓реЗ рдЧрдП
import { UserPageOptions, UserPageController } from "./UserPageController";
import React from "react";

export const userPageView = <P extends UserPageOptions, S>(
    ctrl: UserPageController<P, S>,
    props: P
): JSX.Element => (
    <>
        <div className="user">
            <div className="user-name">
                 : {ctrl.userProfile.getFullname()}
            </div>
            <div className="user-age">
                : {ctrl.userProfile.getAge()}
            </div>
        </div>
        <div className="tarifs">
            {/*    */}
        </div>
    </>
);

UserPageOptionsред рдПрдХ рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓ рдХреЛ рджреЗрдЦрдиреЗ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░реЗрдВ
import { UserProfilService } from "./UserProfilService";
import { TariffService } from "./TariffService";
import { UserProfileDto } from "./UserProfileDto";
import { TariffDto } from "./TariffDto";
import { InsuranceCaseDto } from "./InsuranceCasesDto";
import { autowired } from "first-di";
import { BaseComponent } from "./BaseComponent";
import { userPageView } from "./UserPageview";

export interface UserPageOptions {
    param1?: number;
    param2?: string;
}

//    BaseComponent
export class UserPageController<P extends UserPageOptions, S> extends BaseComponent<P, S> {

    public userProfile: UserProfileDto = new UserProfileDto();
    public insuranceCases: InsuranceCaseDto[] = [];
    public tariffs: TariffDto[] = [];
    public bestTariff: TariffDto | void = void 0;

    //  
    public readonly view = userPageView;

    @autowired()
    private readonly userProfilService!: UserProfilService;

    @autowired()
    private readonly tarifService!: TariffService;

    //  
    constructor(props: P, context: S) {
        super(props, context);
    }

    //   componentDidMount, . BaseComponent
    public activate(): void {
        this.requestUserProfile();
        this.requestTariffs();
    }

    public async requestUserProfile(): Promise<void> {
        try {
            this.userProfile = await this.userProfilService.getUserProfile();
            this.bestTariff = await this.tarifService.findBestTariff(this.userProfile);
            this.forceUpdate();
        } catch (e) {
            console.error(e);
        }
    }

    public async requestTariffs(): Promise<void> {
        try {
            this.tariffs = await this.tarifService.getTariffs();
            this.forceUpdate();
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * ...   ,   ,
     *  ,    
     */
}

BaseComponent рдПрдХ рдШрдЯрдХ рдЬреЛ рд╣рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдврд╛рдВрдЪреЗ рд╕реЗ рдЕрд▓рдЧ рдХрд░рддрд╛ рд╣реИ
import React from "react";

export class BaseComponent<P, S> extends React.Component<P, S> {

    //  view
    public view?: (ctrl: this, props: P) => JSX.Element;

    constructor(props: P, context: S) {
        super(props, context);
        //    
    }

    //      
    public componentDidMount(): void {
        this.activate && this.activate();
    }

    //      
    public shouldComponentUpdate(
        nextProps: Readonly<P>,
        nextState: Readonly<S>,
        nextContext: any
    ): boolean {
        return this.update(nextProps, nextState, nextContext);
    }

    public componentWillUnmount(): void {
        this.dispose();
    }

    public activate(): void {
        //   
    }

    public update(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): boolean {
        //   
        return false;
    }

    public dispose(): void {
        //   
    }

    //   view
    public render(): React.ReactElement<object> {
        if (this.view) {
            return this.view(this, this.props);
        } else {
            return React.createElement("div", {}, "  ");
        }
    }

}


рдЕрдм рд╣рдорд╛рд░рд╛ рд╡рд┐рдЪрд╛рд░ рдПрдХ рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╣реИ, рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдкрддрд╛ рд╣реИ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рдпрд╣ рд╣реИред рд╢рд╛рдпрдж рдЖрдкрдХреЛ рдирд┐рдпрдВрддреНрд░рдХ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреГрд╢реНрдп рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд░реЗрдВ рдЬреИрд╕рд╛ рдХрд┐ рдХреЛрдгреАрдп рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреБрдЫ рд╡рд┐рдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╖рдп рд╣реИред

рдмреБрдирд┐рдпрд╛рджреА рдШрдЯрдХ рдореЗрдВ рд░реВрдкрд░реЗрдЦрд╛ рдХреЗ рдЬреАрд╡рди рдЪрдХреНрд░ рд╕реЗ рдПрдХ рдЕрдореВрд░реНрддрддрд╛ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИред рд╡реЗ рд╕рднреА рд░реВрдкрд░реЗрдЦрд╛рдУрдВ рдореЗрдВ рднрд┐рдиреНрди рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рд╕рднреА рд░реВрдкрд░реЗрдЦрд╛рдУрдВ рдореЗрдВ рд╣реИрдВред рдХреЛрдгреАрдп рд╣реИ ngOnInit, ngOnChanges, ngOnDestroyред рд░рд┐рдПрдХреНрдЯ рдФрд░ рдкреНрд░реАрдХреНрдЯ рдореЗрдВ, рдпрд╣ рдХрдВрдкреЛрдиреЗрдВрдЯрдбрд┐рдорд╛рдЙрдВрдЯ, рд╢реЛ рдХреЙрдВрдкреЛрдиреЗрдВрдЯ рдпреВрдкреАрдбреЗрдЯ, рдХрдВрдкреЛрдиреЗрдВрдЯрд╡реНрдпреВрд▓реЗрдирдЯрд╛рдЙрди рд╣реИред Vue рдореЗрдВ, рдпрд╣ рдмрдирд╛рдпрд╛ рдЧрдпрд╛, рдЕрджреНрдпрддрди рдХрд┐рдпрд╛ рдЧрдпрд╛, рдирд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ред рдорд┐рдереНрд░рд┐рд▓ рдореЗрдВ рдпрд╣ рдСрдиреНрдХреНрд░рд┐рдПрдЯ, рдСрдирдЕрдкрдбреЗрдЯ, рдУрдирд╛рд░реНрдореЛрд╡ рд╣реИред WebCompords рдореЗрдВ, рдпрд╣ рдХрдиреЗрдХреНрдЯ рд╣реИ рдХреЙрд▓рдмреИрдХ, рдПрдЯреНрд░реАрдмреНрдпреВрдЯреЗрдб рдХреЙрд▓рдмреИрдХ, рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯреЗрдб рдХреЙрд▓рдмреИрдХред рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВред рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЗ рдкрд╛рд╕ рд╕рдорд╛рди рдпрд╛ рд╕рдорд╛рди рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдм рд╕рднреА рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкреБрд╕реНрддрдХрд╛рд▓рдп рдШрдЯрдХреЛрдВ рдХреЛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдирд╛рд▓рд┐рдЯрд┐рдХреНрд╕, рдирд┐рдЧрд░рд╛рдиреА, тАЛтАЛрд▓реЙрдЧрд┐рдВрдЧ, рдЖрджрд┐ рдХреЗ рд▓рд┐рдП рдЙрдкрдХрд░рдг рд╢реБрд░реВ рдХрд░рдирд╛ред

рд╣рдо рдкрд░рд┐рдгрд╛рдо рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ


рдпрд╣ рдХреЗрд╡рд▓ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реБрдЖред рдкреВрд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдВрддрд┐рдо рд░реВрдк рд╣реИрдВ:
Main.ts. рд╡рд╣ рдлрд╝рд╛рдЗрд▓ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
import { override } from "first-di";
import { UserProfilRepository } from "./UserProfilRepository";
import { MockUserProfilRepository } from "./MockUserProfilRepository";
import { UserPageController } from "./UserPageController";
import React from "react";
import { render } from "react-dom";

if (process.env.NODE_ENV === "test") {
    override(UserProfilRepository, MockUserProfilRepository);
}

render(React.createElement(UserPageController), document.body);

UserPageViewред рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдШрдЯрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ред
import { UserPageOptions, UserPageController } from "./UserPageController";
import React from "react";

export const userPageView = <P extends UserPageOptions, S>(
    ctrl: UserPageController<P, S>,
    props: P
): JSX.Element => (
    <>
        <div className="user">
            <div className="user-name">
                 : {ctrl.userProfile.getFullname()}
            </div>
            <div className="user-age">
                : {ctrl.userProfile.getAge()}
            </div>
        </div>
        <div className="tarifs">
            {/*    */}
        </div>
    </>
);

UserPageControllerред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдШрдЯрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рддрд░реНрдХ
import { UserProfilService } from "./UserProfilService";
import { TariffService } from "./TariffService";
import { UserProfileDto } from "./UserProfileDto";
import { TariffDto } from "./TariffDto";
import { InsuranceCaseDto } from "./InsuranceCasesDto";
import { autowired } from "first-di";
import { BaseComponent } from "./BaseComponent";
import { userPageView } from "./UserPageview";

export interface UserPageOptions {
    param1?: number;
    param2?: string;
}

export class UserPageController<P extends UserPageOptions, S> extends BaseComponent<P, S> {

    public userProfile: UserProfileDto = new UserProfileDto();
    public insuranceCases: InsuranceCaseDto[] = [];
    public tariffs: TariffDto[] = [];
    public bestTariff: TariffDto | void = void 0;

    public readonly view = userPageView;

    @autowired()
    private readonly userProfilService!: UserProfilService;

    @autowired()
    private readonly tarifService!: TariffService;

    //   componentDidMount, . BaseComponent
    public activate(): void {
        this.requestUserProfile();
        this.requestTariffs();
    }

    public async requestUserProfile(): Promise<void> {
        try {
            this.userProfile = await this.userProfilService.getUserProfile();
            this.bestTariff = await this.tarifService.findBestTariff(this.userProfile);
            this.forceUpdate();
        } catch (e) {
            console.error(e);
        }
    }

    public async requestTariffs(): Promise<void> {
        try {
            this.tariffs = await this.tarifService.getTariffs();
            this.forceUpdate();
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * ...   ,   ,
     *  ,    
     */
}

BaseComponent рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд░рдо рдШрдЯрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдмреЗрд╕ рдХреНрд▓рд╛рд╕
import React from "react";

export class BaseComponent<P, S> extends React.Component<P, S> {

    public view?: (ctrl: this, props: P) => JSX.Element;

    constructor(props: P, context: S) {
        super(props, context);
    }

    public componentDidMount(): void {
        this.activate && this.activate();
    }

    public shouldComponentUpdate(
        nextProps: Readonly<P>,
        nextState: Readonly<S>,
        nextContext: any
    ): boolean {
        return this.update(nextProps, nextState, nextContext);
    }

    public componentWillUnmount(): void {
        this.dispose();
    }

    public activate(): void {
        //   
    }

    public update(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): boolean {
        //   
        return false;
    }

    public dispose(): void {
        //   
    }

    public render(): React.ReactElement<object> {
        if (this.view) {
            return this.view(this, this.props);
        } else {
            return React.createElement("div", {}, "  ");
        }
    }

}

UserProfilServiceред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рддрд░реНрдХ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛
import { UserProfilRepository } from "./UserProfilRepository";
import { UserProfileDto } from "./UserProfileDto";
import { reflection } from "first-di";

@reflection
export class UserProfilService {

    private readonly userProfilRepository: UserProfilRepository;

    constructor(userProfilRepository: UserProfilRepository) {
        this.userProfilRepository = userProfilRepository;
    }

    public async getUserProfile(): Promise<UserProfileDto> {
        return await this.userProfilRepository.getUserProfile();
    }

    /**
     * ...        
     */
}

TariffServiceред рдЯреИрд░рд┐рдл рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рддрд░реНрдХ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛
import { TariffRepository } from "./TariffRepository";
import { TariffDto } from "./TariffDto";
import { UserProfileDto } from "./UserProfileDto";
import { reflection } from "first-di";

@reflection
export class TariffService {

    private readonly tarifRepository: TariffRepository;

    constructor(tarifRepository: TariffRepository) {
        this.tarifRepository = tarifRepository;
    }

    public async getTariffs(): Promise<TariffDto[]> {
        return await this.tarifRepository.requestTariffs();
    }

    public async findBestTariff(userProfile: UserProfileDto): Promise<TariffDto | void> {
        const tariffs = await this.tarifRepository.requestTariffs();
        return tariffs.find((tarif: TariffDto) => {
            const age = userProfile.getAge();
            return age &&
                tarif.ageFrom <= age &&
                age < tarif.ageTo;
        });
    }

    /**
     * ...       
     */
}

UserProfilRepositoryред рд╕рд░реНрд╡рд░ рд╕реЗ рдПрдХ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ, рдЙрд╕реЗ рдЬрд╛рдБрдЪрдиреЗ рдФрд░ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднрдВрдбрд╛рд░
import { UserProfileDto } from "./UserProfileDto";
import { reflection } from "first-di";

@reflection
export class UserProfilRepository {
    public async getUserProfile(): Promise<UserProfileDto> {
        const response = await fetch("./api/user-profile");
        const object = await response.json();
        return new UserProfileDto().fromJSON(object);
    }

    /**
     * ...        
     */
}

MockUserProfilRepository.
import { UserProfileDto } from "./UserProfileDto";
import { reflection } from "first-di";

@reflection //  typescript  
export class MockUserProfilRepository { //   
    public async getUserProfile(): Promise<UserProfileDto> {
        const profile = new UserProfileDto();
        profile.firstName = "";
        profile.lastName = "";
        profile.birthdate = new Date(Date.now() - 1.5e12);
        return Promise.resolve(profile); //   
    }

    /**
     * ...        
     */
}

TariffRepository. ,
import { TariffDto } from "./TariffDto";
import { reflection } from "first-di";

@reflection //  typescript  
export class TariffRepository {
    public async requestTariffs(): Promise<TariffDto[]> {
        const response = await fetch("./api/tariffs");
        const objects: object[] = await response.json();
        return objects.map((object: object) => {
            return new TariffDto().fromJSON(object);
        });
    }

    /**
     * ...        
     */
}

UserProfileDto.
import { Serializable, jsonProperty } from "ts-serializable";

export class UserProfileDto extends Serializable {

    @jsonProperty(String, null)
    public firstName: string | null = null;

    @jsonProperty(String, null)
    public lastName: string | null = null;

    @jsonProperty(Date, null)
    public birthdate: Date | null = null;

    public getAge(): number | null {
        if (this.birthdate) {
            const ageDifMs = Date.now() - this.birthdate.getTime();
            const ageDate = new Date(ageDifMs);
            return Math.abs(ageDate.getUTCFullYear() - 1970);
        }
        return null;
    }

    public getFullname(): string | null {
        return [
            this.firstName ?? "",
            this.lastName ?? ""
        ]
            .join(" ")
            .trim() || null;
    }

}

TariffDto.
import { Serializable, jsonProperty } from "ts-serializable";

export class TariffDto extends Serializable {

    @jsonProperty(Number, null)
    public ageFrom: number = 0;

    @jsonProperty(Number, null)
    public ageTo: number = 0;

    @jsonProperty(Number, null)
    public price: number = 0;

}


рдирддреАрдЬрддрди, рд╣рдореЗрдВ рдмрд╣реБрдд рдХрдо рдорд╛рддреНрд░рд╛ рдореЗрдВ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ (1 рдореВрд▓ рдШрдЯрдХ, рдкреНрд░рддрд┐ рд╡рд░реНрдЧ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 3 рд▓рд╛рдЗрдиреЗрдВ) рдФрд░ рдмрд╣реБрдд рдХрдо рдУрд╡рд░рд╣реЗрдб (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЗрд╡рд▓ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╛рдХреА рд╕рдм рддрд░реНрдХ рд╣реИ) рдХреЗ рд╕рд╛рде рдПрдХ рдореЙрдбреНрдпреВрд▓рд░ рд╕реНрдХреЗрд▓реЗрдмрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдорд┐рд▓рд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдХрд┐рд╕реА рднреА рдкреНрд░рд╕реНрддреБрддрд┐ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдмрдВрдзреЗ рдирд╣реАрдВ рд╣реИрдВред рдЬрдм рдПрдВрдЧреБрд▓рд░ 1 рдХреА рдореГрддреНрдпреБ рд╣реЛ рдЧрдИ, рддреЛ рдХрдИ рдиреЗ рд░рд┐рдПрдХреНрдЯ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред рдЬрдм рдПрдВрдЧреБрд▓рд░ 2 рдХреЗ рд▓рд┐рдП рдбреЗрд╡рд▓рдкрд░реНрд╕ рдмрд╛рд╣рд░ рднрд╛рдЧ рдЧрдП, рддреЛ рд╡рд┐рдХрд╛рд╕ рдХреА рдЧрддрд┐ рдХреЗ рдХрд╛рд░рдг рдХрдИ рдХрдВрдкрдирд┐рдпрд╛рдВ рдкреАрдбрд╝рд┐рдд рд╣реЛрдиреЗ рд▓рдЧреАрдВред рдЬрдм рд░рд┐рдПрдХреНрдЯ рдлрд┐рд░ рд╕реЗ рдорд░ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рдврд╛рдВрдЪреЗ рдФрд░ рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рд╕реЗ рдЬреБрдбрд╝реЗ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЪрд┐рддрд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд╕рд╛рде рдЖрдк рдврд╛рдВрдЪреЗ рдХреЛ рдмрд╛рдВрдзрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВред

Redux рдкрд░ рдХреНрдпрд╛ рдлрд╛рдпрджрд╛ рд╣реИ?


рдЕрдВрддрд░ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдЬрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдврд╝рддрд╛ рд╣реИ рддреЛ Redux рдХреИрд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИред
Redux

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЖрд░реЗрдЦ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, Redux рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреА рд╡реГрджреНрдзрд┐ рдХреЗ рд╕рд╛рде рд▓рдВрдмрд╡рдд, рд╕реНрдЯреЛрд░ рдФрд░ Reducers рдХреА рд╕рдВрдЦреНрдпрд╛ рднреА рдмрдврд╝ рдЬрд╛рддреА рд╣реИ рдФрд░ рдПрдХ рдЕрдбрд╝рдЪрди рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреА рд╣реИред рдФрд░ рд╕реНрдЯреЛрд░ рдХреЗ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдФрд░ рд╕рд╣реА Reducer рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдУрд╡рд░рд╣реЗрдб рдХреА рдорд╛рддреНрд░рд╛ рдкреЗрд▓реЛрдб рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛрдиреЗ рд▓рдЧреА рд╣реИред

рдЖрдк рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдордзреНрдпрдо рдЖрдХрд╛рд░ рдХреЗ рдЖрд╡реЗрджрди рдкрд░ рдкреЗрд▓реЛрдб рдХреЗ рдЕрдиреБрдкрд╛рдд рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
let create = new Function([
"return {",
...new Array(100).fill(1).map((val, ind) => `param${ind}:${ind},`),
"}"
].join(""));

let obj1 = create();

console.time("store recreation time");
let obj2 = {
    ...obj1,
    param100: 100 ** 2
}
console.timeEnd("store recreation time");

console.time("clear logic");
let val = 100 ** 2;
console.timeEnd("clear logic");

console.log(obj2, val);

// store recreation time: 0.041015625ms
// clear logic: 0.0048828125ms

рд╕реНрдЯреЛрд░ рдХреЛ 100 рдЧреБрдгреЛрдВ рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реНрдХ рд╕реЗ 8 рдЧреБрдирд╛ рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧрд╛ред 1000 рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рде, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 50 рдЧреБрдирд╛ рдЕрдзрд┐рдХ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рдПрдХ рдкреВрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рдЬрдиреНрдо рджреЗ рд╕рдХрддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рдХреЙрд▓ рдХреЛ рдкрдХрдбрд╝рдирд╛ рдФрд░ рдбреАрдмрдЧ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рддрд░реНрдХ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕реНрдЯреЛрд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП 0.04 рдПрдордПрд╕ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИ рдФрд░ рдзреАрдорд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдХреЛрд░ i7 рдкреНрд░реЛрд╕реЗрд╕рд░ рдкрд░ 0.04 рдПрдордПрд╕ рдФрд░ рдПрдХ рдПрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╣реИред рдХрдордЬреЛрд░ рдореЛрдмрд╛рдЗрд▓ рдкреНрд░реЛрд╕реЗрд╕рд░ рдФрд░ рдЗрд╕ рддрдереНрдп рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдПрдХ рдПрдХрд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛рд░реНрд░рд╡рд╛рдИ рджрд░реНрдЬрдиреЛрдВ рдХрд╛рд░реНрд░рд╡рд╛рдЗрдпрд╛рдВ рдХрд░ рд╕рдХрддреА рд╣реИ, рдпрд╣ рд╕рдм рдЗрд╕ рддрдереНрдп рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЧрдгрдирд╛ 16 рдПрдордПрд╕ рдореЗрдВ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рдФрд░ рдПрдХ рднрд╛рд╡рдирд╛ рдкреИрджрд╛ рд╣реЛрддреА рд╣реИ рдХрд┐ рдЖрд╡реЗрджрди рдзреАрдорд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред

рдЖрдЗрдП рддреБрд▓рдирд╛ рдХрд░реЗрдВ рдХрд┐ рдХреНрд▓реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╕реЗ рдмрдврд╝рддрд╛ рд╣реИ:
рд╢реБрджреНрдз рд╡рд╛рд╕реНрддреБрдХрд▓рд╛

рдЬреИрд╕рд╛ рдХрд┐ рдкрд░рддреЛрдВ рдХреЗ рдмреАрдЪ рддрд░реНрдХ рдФрд░ рдЬрд┐рдореНрдореЗрджрд╛рд░рд┐рдпреЛрдВ рдХреЗ рдЕрд▓рдЧрд╛рд╡ рдХреЗ рдХрд╛рд░рдг рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЖрд╡реЗрджрди рдХреНрд╖реИрддрд┐рдЬ рд░реВрдк рд╕реЗ рдмрдврд╝рддрд╛ рд╣реИред рдпрджрд┐ рдХрд┐рд╕реА рднреА рдШрдЯрдХ рдХреЛ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдпрд╣ рдЙрд╕рдХреЗ рдХрд╛рд░реНрдп рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╕реЗрд╡рд╛рдУрдВ рдХреЛ рдЫреВрдиреЗ рдХреЗ рдмрд┐рдирд╛ рд╕рдВрдмрдВрдзрд┐рдд рд╕реЗрд╡рд╛ рдХреА рдУрд░ рдореБрдбрд╝ рдЬрд╛рдПрдЧрд╛ред рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдХреЗрд╡рд▓ рдПрдХ рдШрдЯрдХ рдХреЛ рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдбреЗрдЯрд╛ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдЪреЗрди рдмрд╣реБрдд рдЫреЛрдЯреА рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдФрд░ рдЕрдзрд┐рдХрддрдо 4 рдХреЛрдб рдХреА рдЫрд▓рд╛рдВрдЧ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЖрд╡рд╢реНрдпрдХ рддрд░реНрдХ рдвреВрдВрдв рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдбреАрдмрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдЧрд░ рд╣рдо рдПрдХ рдИрдВрдЯ рдХреА рджреАрд╡рд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд╛рджреГрд╢реНрдп рдЦреАрдВрдЪрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЗрд╕ рджреАрд╡рд╛рд░ рд╕реЗ рдХрд┐рд╕реА рднреА рдИрдВрдЯ рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рджреАрд╡рд╛рд░ рдХреА рд╕реНрдерд┐рд░рддрд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рдЗрд╕реЗ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред

рдмреЛрдирд╕ 1: рдврд╛рдВрдЪреЗ рдХреЗ рдШрдЯрдХреЛрдВ рдХреА рдмрдврд╝реА рд╣реБрдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛


рдПрдХ рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╕реНрддреБрддрд┐ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдШрдЯрдХреЛрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреВрд░рдХ рдпрд╛ рдмрджрд▓рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рджреГрд╢реНрдп рдореЗрдВ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреВрд░реЗ рдЖрд╡реЗрджрди рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд░рддреА рд╣реИ, рдЕрдЧрд░ рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
export class BaseComponent<P, S> extends React.Component<P, S> {

    ...

    public render(): React.ReactElement<object> {
        try {
            if (this.view) {
                return this.view(this, this.props);
            } else {
                return React.createElement("div", {}, "  ");
            }
        } catch (e) {
            return React.createElement(
                "div",
                { style: { color: "red" } },
                `    : ${e}`
            );
        }
    }

}

рдЕрдм рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗрд╡рд▓ рдЙрд╕ рдШрдЯрдХ рдХреЛ рдирд╣реАрдВ рдЦреАрдВрдЪреЗрдЧреА рдЬрд┐рд╕рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╣реБрдИ рдереАред рдЙрд╕реА рд╕рд░рд▓ рддрд░реАрдХреЗ рд╕реЗ, рдЖрдк рдирд┐рдЧрд░рд╛рдиреА, тАЛтАЛрд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рдЕрдиреНрдп рдирд┐рд╢реНрддрд┐рдХреА рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдмреЛрдирд╕ 2: рдбреЗрдЯрд╛ рд╕рддреНрдпрд╛рдкрди


рдбреЗрдЯрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдФрд░ рдкрд░рддреЛрдВ рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореЙрдбрд▓ рдореЗрдВ рдЕрд╡рд╕рд░ рдХрд╛ рдПрдХ рдмрдбрд╝рд╛ рдорд╛рд░реНрдЬрд┐рди рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рд╡рд░реНрдЧ-рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ , рддреЛ рдмрд╕ рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕ рдХреЛ рд▓рдЯрдХрд╛рдХрд░, рдЖрдк рдЗрди рдореЙрдбрд▓реЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдорд╛рдиреНрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдереЛрдбрд╝рд╛ рдкрд░рд┐рд╢реЛрдзрди рдХреЗ рд╕рд╛рде, рдЖрдк рд╡реЗрдм рд░реВрдкреЛрдВ рдХреЛ рдорд╛рдиреНрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдмреЛрдирд╕ 3: рд╕рдВрд╕реНрдерд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдЖрдкрдХреЛ рд╕реНрдерд╛рдиреАрдп рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЯрд╛рдЗрдкреЛрд░реНрдо рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЖрдкрдХреЗ рдореЙрдбрд▓ рдЙрди рд╕рдВрд╕реНрдерд╛рдУрдВ рдореЗрдВ рдмрджрд▓ рдЬрд╛рдПрдВрдЧреЗ рдЬрд┐рдирдХреЗ рджреНрд╡рд╛рд░рд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рдЙрддреНрдкрдиреНрди рд╣реЛрдЧрд╛ рдФрд░ рдЪрд▓реЗрдЧрд╛ред

рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдзрдиреНрдпрд╡рд╛рдж


рдпрджрд┐ рдЖрдкрдХреЛ рд▓реЗрдЦ рдпрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд╕рдВрдж рдЖрдпрд╛, рддреЛ рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдбрд░реЛ рдорддред рдпрджрд┐ рдЖрдк рдПрдХ Redux рдЕрдиреБрдпрд╛рдпреА рд╣реИрдВ рдФрд░ рдЖрдк рдЕрд╕рд╣рдорддрд┐ рдХреА рддрд░рд╣ рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдмрддрд╛рдПрдВ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдХреИрд╕реЗ рдорд╛рдкрддреЗ, рдкрд░рдЦрддреЗ рдФрд░ рдорд╛рдиреНрдп рдХрд░рддреЗ рд╣реИрдВред

All Articles