{"id":309903,"date":"2020-09-14T15:00:31","date_gmt":"2020-09-14T15:00:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=309903"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=309903","title":{"rendered":"5 \u0441\u043e\u0432\u0435\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u043a\u0430\u0447\u043a\u0438 \u0441\u0432\u043e\u0438\u0445 \u043d\u0430\u0432\u044b\u043a\u043e\u0432 \u0432 Angular"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/519052\/\">\n<p>\u042d\u0442\u0438\u043c \u043b\u0435\u0442\u043e\u043c \u043c\u044b \u0441 <a href=\"https:\/\/habr.com\/ru\/users\/MarsiBarsi\/\" rel=\"noopener noreferrer nofollow\"><u>\u0420\u043e\u043c\u043e\u0439<\/u><\/a> \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0441\u0435\u0440\u0438\u044e \u0442\u0432\u0438\u0442\u043e\u0432 \u0441 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u0441\u043e\u0432\u0435\u0442\u0430\u043c\u0438 \u0438 \u043f\u0440\u0438\u0435\u043c\u0430\u043c\u0438 \u043f\u043e Angular. \u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e \u0442\u0435\u043f\u043b\u043e \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u043e \u044d\u0442\u0443 \u0438\u043d\u0438\u0446\u0438\u0430\u0442\u0438\u0432\u0443, \u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0431\u043e\u0431\u0449\u0430\u044e\u0449\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e.  \u0412\u043e\u0442 \u043c\u043e\u0438 5 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438. \u042d\u0442\u0438 \u0441\u043e\u0432\u0435\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438\u0437 <a href=\"https:\/\/twitter.com\/Waterplea\" rel=\"noopener noreferrer nofollow\"><u>\u043c\u043e\u0435\u0433\u043e \u0442\u0432\u0438\u0442\u0442\u0435\u0440\u0430<\/u><\/a>. \u041e\u043d\u0438 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0432\u0430\u043c \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u043d\u0430\u0432\u044b\u043a\u0438 \u0438\u043b\u0438 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0434\u0430\u0434\u0443\u0442 \u043f\u0430\u0440\u0443 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u0435\u043c\u043e\u0432.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/249\/480\/208\/249480208609a7a1f7db2d01affcbcbc.png\" width=\"4585\" height=\"2084\"><figcaption><\/figcaption><\/figure>\n<h2>1. \u0420\u0430\u0437\u0431\u0435\u0440\u0438\u0442\u0435\u0441\u044c \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439<\/h2>\n<p>\u0412 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0445 \u0443\u0433\u043b\u0443\u0431\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 Angular. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/habr.com\/ru\/post\/327004\/\" rel=\"noopener noreferrer nofollow\"><u>\u0432\u043e\u0442 \u044d\u0442\u0430.<\/u><\/a> \u0422\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0441\u0432\u0435\u0436\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u044b \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043e\u0432\u0435\u0442\u0430\u043c.<\/p>\n<h3>\u041e\u0441\u043d\u043e\u0432\u044b<\/h3>\n<p>\u0412 Angular \u0434\u0432\u0430 \u0440\u0435\u0436\u0438\u043c\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439: <code>Default<\/code> \u0438 <code>OnPush<\/code>. \u041f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 <em><strong>tick<\/strong><\/em> \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u0438\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <em>Zone.js<\/em>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0430\u0442\u0447\u0438\u0442 \u0432\u0441\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0440\u043e\u0434\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u043f\u0440\u043e\u043c\u0438\u0441\u043e\u0432. \u0412\u0442\u043e\u0440\u043e\u0439 \u0440\u0435\u0436\u0438\u043c \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u0442 view \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0432 \u043d\u0435\u043c \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u043b\u0443\u0448\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<h3>Default vs OnPush<\/h3>\n<p>\u041f\u043e \u043f\u0440\u0430\u0432\u0434\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u0432\u0440\u044f\u0434 \u043b\u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c <code>Default<\/code>. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0438\u0448\u0438\u0442\u0435 \u043a\u043e\u0434 \u0442\u0430\u043a, \u043a\u0430\u043a \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0438 \u0432\u044b \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0435\u0442\u0435 \u0432 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u0441 <code>OnPush<\/code>. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 <strong>\u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043c\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435<\/strong>. \u0415\u0441\u043b\u0438 \u0432\u0430\u0448\u0438 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u043d\u0435\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435, <code>OnPush<\/code> \u043f\u043e\u0434\u0446\u0435\u043f\u0438\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442 \u0432\u044c\u044e.<\/p>\n<p>\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0447\u0435\u0440\u0435\u0437 <code>@HostListener<\/code> Angular \u0437\u0430\u043c\u0435\u0442\u0438\u0442 \u0438 \u0432 <code>OnPush<\/code>. \u041d\u043e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 RxJS? \u0412\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u044c <code>ChangeDetectorRef<\/code> \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>markForCheck()<\/code>, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u0414\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 <code>async<\/code> \u043f\u0430\u0439\u043f, \u0435\u0441\u043b\u0438 \u0441\u0442\u0440\u0438\u043c \u0432 \u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430. \u041e\u043d \u0441\u0430\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438 \u0432\u043e\u0437\u044c\u043c\u0435\u0442 \u043d\u0430 \u0441\u0435\u0431\u044f \u043e\u0442\u043f\u0438\u0441\u043a\u0443.&nbsp;<\/p>\n<p>\u0412\u0430\u043c \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d:<\/p>\n<pre><code class=\"htmlmixed\">&lt;div *ngIf=\"stream$ | async as result\"&gt; &nbsp;&nbsp;&nbsp;&nbsp;\u2026 &lt;\/div&gt;<\/code><\/pre>\n<p>\u041d\u043e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0432\u0430\u0436\u043d\u044b \u0442\u0430\u043a\u0436\u0435 <strong>falsy<\/strong>-\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b? \u041c\u043e\u0436\u043d\u043e \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u044c \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438\u0437 ngIf \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0443. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044c\u044e:<\/p>\n<p><iframe id=\"5f5f571d5e0ed38aa206cf93\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f571d5e0ed38aa206cf93\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">@Directive({   selector: \"[ngLet]\" }) export class LetDirective&lt;T&gt; {   @Input()   ngLet: T;    constructor(     @Inject(ViewContainerRef) container: ViewContainerRef,     @Inject(TemplateRef) templateRef: TemplateRef&lt;LetContext&lt;T&gt;&gt;   ) {     container.createEmbeddedView(templateRef, new LetContext&lt;T&gt;(this));   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>NgZone<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043d\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 <code>OnPush<\/code>, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438. \u0417\u0430\u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u0435 <code>NgZone<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0439\u0442\u0435 \u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 <code>.runOutsideAngular()<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0445 \u0442\u0438\u043a\u043e\u0432 \u0432 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u0414\u0430\u0436\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <code>Default<\/code> \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u044d\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u042d\u0442\u043e \u0443\u043c\u0435\u0441\u0442\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f \u0447\u0430\u0441\u0442\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a <code>mousemove<\/code> \u0438\u043b\u0438 <code>scroll<\/code>. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u0432 RxJS-\u0441\u0442\u0440\u0438\u043c\u0430\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0432\u0443\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432: \u043e\u0434\u0438\u043d \u2014 \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0437\u043e\u043d\u044b, \u0434\u0440\u0443\u0433\u043e\u0439 \u2014 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0432 \u043d\u0435\u0435, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439:<\/p>\n<p><iframe id=\"5f5f573b5f535f8ab4ec3d77\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f573b5f535f8ab4ec3d77\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">class ZonefreeOperator&lt;T&gt; implements Operator&lt;T, T&gt; {   constructor(private readonly zone: NgZone) {}    call(observer: Observer&lt;T&gt;, source: Observable&lt;T&gt;): TeardownLogic {     return this.zone.runOutsideAngular(       () =&gt; source.subscribe(observer)     );   } }  export function zonefull&lt;T&gt;(zone: NgZone): MonoTypeOperatorFunction&lt;T&gt; {   return map(value =&gt; zone.run(() =&gt; value)); }  export function zonefree&lt;T&gt;(zone: NgZone): MonoTypeOperatorFunction&lt;T&gt; {   return source =&gt; source.lift(new ZonefreeOperator(zone)); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<blockquote>\n<p><em>\u0415\u0449\u0435 \u043e\u0434\u0438\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0441 <\/em><code>@HostListener<\/code><em>, \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <\/em><code>EventManagerPlugin<\/code><em>. \u041c\u044b \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u043b\u0438 open-source-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <\/em><a href=\"https:\/\/github.com\/TinkoffCreditSystems\/ng-event-plugins\" rel=\"noopener noreferrer nofollow\"><em><u>ng-event-plugins.<\/u><\/em><\/a><em> \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u0441\u0435\u0438\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u0447\u0438\u0442\u0430\u0439\u0442\u0435 <\/em><a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/492766\/\" rel=\"noopener noreferrer nofollow\"><em><u>\u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/u><\/em><\/a><\/p>\n<\/blockquote>\n<h2>2. \u0425\u043e\u0440\u043e\u0448\u0435\u043d\u044c\u043a\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0438\u0442\u0435\u0441\u044c \u0432 RxJS<\/h2>\n<p>RxJS \u2014 \u043e\u0447\u0435\u043d\u044c \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442. \u041c\u044b \u0432\u0441\u0435 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u0442\u043e\u0439 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u043c\u0435\u0440\u0435, \u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u0435\u0435 \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u0438\u043c \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e<strong> <\/strong>\u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c. \u041e\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u0442\u0440\u0438\u043c\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u2014&nbsp;<\/p>\n<p><iframe id=\"5f5f4f7699fe6819269a176b\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f4f7699fe6819269a176b\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<p>\u2014 \u0434\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0443 \u0432\u0430\u0441 \u0441\u043a\u0440\u043e\u043b\u043b \u0438\u043b\u0438 \u0438\u043d\u0435\u0440\u0446\u0438\u043e\u043d\u043d\u044b\u0439:<\/p>\n<p><iframe id=\"5f5f4fde1958dd1942e0e6de\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f4fde1958dd1942e0e6de\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435, \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0448\u0430\u043f\u043a\u0443, \u0438\u0441\u0447\u0435\u0437\u0430\u044e\u0449\u0443\u044e \u043f\u0440\u0438 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0435 \u0441\u0430\u0439\u0442\u0430 \u0432\u043d\u0438\u0437. \u0421\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e CSS \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 RxJS:<\/p>\n<p><iframe id=\"5f5f4feae3f603193557f2df\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f4feae3f603193557f2df\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">@Directive({   selector: \"[sticky]\",   providers: [DestroyService] }) export class StickyDirective {   constructor(     @Inject(DestroyService) destroy$: Observable&lt;void&gt;,     @Inject(WINDOW) windowRef: Window,     renderer: Renderer2,     { nativeElement }: ElementRef&lt;HTMLElement&gt;   ) {     fromEvent(windowRef, \"scroll\")       .pipe(         map(() =&gt; windowRef.scrollY),         pairwise(),         map(([prev, next]) =&gt; next &lt; THRESHOLD || prev &gt; next),         distinctUntilChanged(),         startWith(true),         takeUntil(destroy$)       )       .subscribe(stuck =&gt; {         renderer.setAttribute(           nativeElement,            \"data-stuck\",            String(stuck)         );       });   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043b\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u0446\u0435\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u043d\u0438\u0435 RxJS \u0434\u043b\u044f Angular-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0432 \u0434\u043e\u043b\u0433\u043e\u0441\u0440\u043e\u0447\u043d\u043e\u0439 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0435. \u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 RxJS \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0435\u043a\u043e\u0435\u0433\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u044b, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u043c\u044b\u0441\u043b\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438. \u041d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u0442\u0435, \u0432\u0430\u0448 \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u0435\u0442 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u0435\u0435 \u0438 \u043b\u0435\u0433\u0447\u0435 \u0432 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435.<\/p>\n<p>\u0422\u0443\u0442 \u043e\u0441\u043e\u0431\u043e \u043d\u0435\u0447\u0435\u0433\u043e \u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u0442\u044c, \u043a\u0440\u043e\u043c\u0435 \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0432\u0430\u0442\u044c\u0441\u044f . \u0415\u0441\u043b\u0438 \u0432\u0438\u0434\u0438\u0442\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 RxJS, \u2014 \u043f\u043e\u043f\u044b\u0442\u0430\u0439\u0442\u0435\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e. \u0418\u0437\u0431\u0435\u0433\u0430\u0439\u0442\u0435 \u0441\u0430\u0439\u0434-\u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a. \u0414\u0435\u0440\u0436\u0438\u0442\u0435 \u0441\u0432\u043e\u0438 \u0441\u0442\u0440\u0438\u043c\u044b \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0438 \u0441\u043b\u0435\u0434\u0438\u0442\u0435 \u0437\u0430 \u0443\u0442\u0435\u0447\u043a\u0430\u043c\u0438 \u043f\u0430\u043c\u044f\u0442\u0438 (\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u0434\u0430\u043b\u044c\u0448\u0435).<\/p>\n<h2>3. \u0412\u044b\u0436\u0438\u043c\u0430\u0439\u0442\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0438\u0437 TypeScript<\/h2>\n<p>\u041c\u044b \u0432\u0441\u0435 \u043f\u0438\u0448\u0435\u043c Angular-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 TypeScript. \u041d\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u043b\u044c\u0437\u0443, \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u042f \u0440\u0435\u0434\u043a\u043e \u0432\u0438\u0436\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0441 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c <code>strict: true<\/code>. \u0412\u0430\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e. \u041e\u043d\u043e \u0441\u043f\u0430\u0441\u0435\u0442 \u0432\u0430\u0441 \u043e\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 <em>cannot read property of null<\/em> \u0438 <em>undefined is not a function<\/em>.<\/p>\n<h3>\u0414\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438<\/h3>\n<p>\u0412 TypeScript \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438 \u2014 \u0434\u043b\u044f \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u0442\u0438\u043f, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c, \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d. \u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u043e\u0432, \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043e\u043a \u0438 \u0441\u0443\u0436\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0430\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0440\u0443\u0442\u043e\u0439 API. \u041f\u043e\u0447\u0442\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u0439\u043f\u043a\u0430\u0441\u0442. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e RxJS-\u043c\u0435\u0442\u043e\u0434\u0430 <code>fromEvent<\/code>:<\/p>\n<p><iframe id=\"5f5f506f5f535f8ab4ec3d76\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f506f5f535f8ab4ec3d76\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">\/\/ \u0422\u0438\u043f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c currentTarget export type EventWith&lt;   E extends Event,   T extends FromEventTarget&lt;E&gt; &gt; = E &amp; {   readonly currentTarget: T; };  \/\/ \u0422\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 fromEvent export function typedFromEvent&lt;   E extends keyof GlobalEventHandlersEventMap,   T extends FromEventTarget&lt;EventWith&lt;GlobalEventHandlersEventMap[E], T&gt;&gt; &gt;(   target: T,   event: E,   options: AddEventListenerOptions = {}, ): Observable&lt;EventWith&lt;GlobalEventHandlersEventMap[E], T&gt;&gt; {   return fromEvent(target, event, options); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421 \u043d\u0438\u043c \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438\u043c\u0435\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0442\u0438\u043f, \u0430 <code>currentTarget<\/code> \u2014 \u044d\u0442\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b \u0435\u0433\u043e \u0441\u043b\u0443\u0448\u0430\u0435\u0442\u0435.<\/p>\n<blockquote>\n<p><em>API, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0430\u0445, \u0445\u043e\u0440\u043e\u0448\u0438 \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0435 \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u044b \u043d\u0430 \u0444\u043e\u0440\u043c\u0430\u0442 \u0434\u0430\u043d\u043d\u044b\u0445. \u0410 \u0437\u043d\u0430\u0447\u0438\u0442, \u0438\u0445 \u043b\u0435\u0433\u043a\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/em><\/p>\n<\/blockquote>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u043c\u0430\u043b\u043e \u0441\u0442\u0430\u0442\u0435\u0439 \u043e \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0439 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0432\u0441\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0442\u0440\u044e\u043a\u0430\u0445 \u0441 TypeScript. \u042f \u043e\u0447\u0435\u043d\u044c \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u0437\u043d\u0430\u043d\u0438\u044f \u0432 \u044d\u0442\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u043a\u043e\u0434. \u041c\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u043e\u0432\u0435\u0442: \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>any<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a, \u0431\u043e\u043b\u0435\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 <code>unknown<\/code>.<\/p>\n<h3>\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b<\/h3>\n<p>\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b TypeScript, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b. \u041f\u0440\u0438 \u0443\u043c\u0435\u043b\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0432\u0430\u0448 \u043a\u043e\u0434. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0431\u044b\u0432\u0430\u044e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u0442\u0438\u043f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439, \u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442: \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438\u043b\u0438 \u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430, \u0445\u043e\u0442\u044f \u0442\u0438\u043f \u0438 \u0442\u0430\u043c, \u0438 \u0442\u0430\u043c \u2014 <code>number<\/code>. TypeScript \u0442\u0430\u043a\u043e\u0435 \u043d\u0435 \u043e\u0442\u043b\u043e\u0432\u0438\u0442, \u043d\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 runtime \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430:<\/p>\n<p><iframe id=\"5f5f50ba1958dd1942e0e6df\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f50ba1958dd1942e0e6df\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">export function assert&lt;T, K extends keyof T&gt;(   assertion: (input: T[K]) =&gt; boolean,   messsage: string ): PropertyDecorator {   return (target, key) =&gt; {     Object.defineProperty(target, key, {       set(this: T, initialValue: T[K]) {         let currentValue = initialValue;          Object.defineProperty(this, key, {           get(): T[K] {             return currentValue;           },           set(this: T, value: T[K]) {             console.assert(assertion(value), messsage);             currentValue = value;           }         });       }     });   }; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b \u0437\u043d\u0430\u043b\u0438, \u0447\u0442\u043e \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 <code>super()<\/code>? Angular \u0441\u0430\u043c \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e \u0437\u0430 \u0432\u0430\u0441, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0435:<\/p>\n<p><iframe id=\"5f5f50e146103f8a958c9665\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f50e146103f8a958c9665\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<p>\u0415\u0449\u0435 \u043e\u0434\u0438\u043d \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u2014 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043a\u0443\u0441\u043e\u043a \u043a\u043e\u0434\u0430 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f Web Audio API \u0432 Angular, \u0433\u0434\u0435 \u043c\u044b <a href=\"https:\/\/github.com\/ng-web-apis\/audio\/blob\/c7db781a31d9a945700b0f6bce055bd66d0d4810\/projects\/audio\/src\/utils\/process-audio-param.ts\" rel=\"noopener noreferrer nofollow\"><u>\u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0431\u0430\u0439\u043d\u0434\u0438\u043d\u0433 \u0432 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/u><\/a> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/github.com\/ng-web-apis\/audio\/blob\/master\/projects\/audio\/src\/decorators\/audio-param.ts\" rel=\"noopener noreferrer nofollow\"><u>\u0441\u0442\u0440\u043e\u0433\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430.<\/u><\/a> \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0441\u0430\u043c\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/493622\/\" rel=\"noopener noreferrer nofollow\"><u>\u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0442\u0443\u0442.<\/u><\/a><\/p>\n<h2>4. Dependency Injection. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0435\u0433\u043e \u043f\u043e\u0447\u0430\u0449\u0435<\/h2>\n<p>DI \u2014 \u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u0438\u0447\u0438\u043d, \u043f\u043e\u0447\u0435\u043c\u0443 Angular \u0442\u0430\u043a\u043e\u0439 \u043c\u043e\u0449\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0434\u0430\u0436\u0435 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u0430. \u041d\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0447\u0430\u0441\u0442\u043e \u0435\u0433\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u043e \u043f\u043e\u043b\u043d\u043e\u0439.<\/p>\n<blockquote>\n<p><em>\u041c\u043e\u0433\u0443 \u043f\u043e\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u0442\u044c <\/em><a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/516622\/\" rel=\"noopener noreferrer nofollow\"><em><u>\u043d\u0430\u0448\u0443 \u0441\u0442\u0430\u0442\u044c\u044e, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u0443\u044e DI<\/u><\/em><\/a><em>, \u0447\u0442\u043e\u0431\u044b \u043e\u0441\u0432\u043e\u0438\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c.<\/em><\/p>\n<\/blockquote>\n<h3>RxJS<\/h3>\n<p>\u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u043e\u0432\u0435\u0442\u043e\u0432, \u0432\u044b\u0448\u0435 \u044f \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0431\u044b\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a \u0443\u0442\u0435\u0447\u043a\u0430\u043c \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 RxJS. \u0413\u043b\u0430\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e, <strong>\u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u0441\u0442\u0440\u0438\u043c \u0440\u0443\u043a\u0430\u043c\u0438, \u0432\u0430\u043c \u0436\u0435 \u0438 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043e\u0442 \u043d\u0435\u0433\u043e \u043e\u0442\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f<\/strong>. \u0418\u0434\u0438\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 Angular \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432 \u0441\u0435\u0440\u0432\u0438\u0441:<\/p>\n<p><iframe id=\"5f5f512099fe6819269a176c\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f512099fe6819269a176c\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">@Injectable() export class DestroyService extends Subject&lt;void&gt; implements OnDestroy {     ngOnDestroy() {         this.next();         this.complete();     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u0449\u0438\u0435 \u0441\u0442\u0440\u0438\u043c\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u0432 DI. \u041d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u043d\u0430 \u0431\u0430\u0437\u0435 <code>requestAnimationFrame<\/code> \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0442\u043e\u043a\u0435\u043d \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0435\u0433\u043e. \u0412\u044b \u0434\u0430\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043d\u0435\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0437\u043e\u043d\u044b, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435:<\/p>\n<p><iframe id=\"5f5f51379a7d1419651d09b5\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f51379a7d1419651d09b5\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<h3>\u0422\u043e\u043a\u0435\u043d\u044b<\/h3>\n<p>DI \u2014 \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442\u0435 \u043e\u0442 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432\u0440\u043e\u0434\u0435 <code>window<\/code> \u0438\u043b\u0438 <code>navigator<\/code> \u2014 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043e \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Angular Universal \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438. \u0422\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0435 \u0435\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438. \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0431\u0435\u0437 \u0442\u0440\u0443\u0434\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u0442\u043e\u043a\u0435\u043d\u044b. \u0412\u043d\u0443\u0442\u0440\u0438 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u043f\u0440\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0436\u0435\u043a\u0442\u043e\u0440. \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u043e \u043f\u0430\u0440\u0430 \u0441\u0442\u0440\u043e\u043a \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <code>WINDOW<\/code> \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u0431\u0430\u0437\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e <code>DOCUMENT<\/code>:<\/p>\n<p><iframe id=\"5f5f51ad99fe6819269a176d\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f51ad99fe6819269a176d\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">export const WINDOW = new InjectionToken&lt;Window&gt;(   'An abstraction over global window object',   {     factory: () =&gt; {       const {defaultView} = inject(DOCUMENT);        if (!defaultView) {         throw new Error('Window is not available');       }        return defaultView;     },   }, );<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<blockquote>\n<p><em>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u043d\u0430 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <\/em><a href=\"https:\/\/github.com\/ng-web-apis\/common\" rel=\"noopener noreferrer nofollow\"><em><u>\u043d\u0430\u0448\u0443 open-source-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443<\/u><\/em><\/a><em>, \u0433\u0434\u0435 \u043c\u044b \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043c\u043d\u043e\u0433\u0438\u0435 \u0442\u0430\u043a\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u044b. \u0410 \u0434\u043b\u044f Angular Universal \u0435\u0441\u0442\u044c <\/em><a href=\"https:\/\/github.com\/ng-web-apis\/universal\" rel=\"noopener noreferrer nofollow\"><em><u>\u0435\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430-\u0441\u0435\u0441\u0442\u0440\u0430<\/u><\/em><\/a><em> \u0441 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430\u043c\u0438. \u041d\u0435 \u0441\u0442\u0435\u0441\u043d\u044f\u0439\u0442\u0435\u0441\u044c, <\/em><a href=\"https:\/\/github.com\/ng-web-apis\/common\/issues\" rel=\"noopener noreferrer nofollow\"><em><u>\u043f\u0438\u0448\u0438\u0442\u0435 \u043d\u0430\u043c<\/u><\/em><\/a><em>, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0435\u0449\u0435 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0442\u043e\u043a\u0435\u043d.<\/em><\/p>\n<\/blockquote>\n<p>\u0422\u043e\u043a\u0435\u043d\u044b \u0438 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u0434\u0430\u044e\u0442 \u043c\u0430\u0441\u0441\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439. \u0412 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 DI \u043e\u043d\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0447\u0435\u043d\u044c \u043c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u043c. \u041c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 <a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/507906\/\" rel=\"noopener noreferrer nofollow\"><u>\u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/u><\/a><\/p>\n<h2>5. \u0411\u0440\u043e\u0441\u0430\u0439\u0442\u0435 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0432 \u0431\u0435\u0437\u0434\u043d\u0443, \u043a\u0430\u043a \u0412\u0435\u0439\u0434\u0435\u0440<\/h2>\n<p>Angular \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c\u0438 \u043f\u043e\u0434\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442 \u043d\u0430\u0441 \u043a \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u043f\u043e\u0434\u0445\u043e\u0434\u0443. \u042f \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b \u0435\u0433\u043e. \u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e \u0435\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u0445 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u042f \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0430\u043c \u0432\u0430\u043c \u0447\u0435\u0442\u043a\u0438\u0439 \u0441\u043e\u0432\u0435\u0442: <strong>\u043f\u0438\u0448\u0438\u0442\u0435 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043a\u043e\u0434<\/strong>. \u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u0438\u0432\u044b\u043a\u043d\u0435\u0442\u0435, \u0442\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u0435, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u0441\u0442\u0430\u043b\u043e \u043b\u0443\u0447\u0448\u0435.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ee5\/f84\/ca4\/ee5f84ca4fc196adb2d4c0606643a18e.gif\" width=\"500\" height=\"200\"><figcaption><\/figcaption><\/figure>\n<h3>\u0413\u0435\u0442\u0442\u0435\u0440\u044b<\/h3>\n<p>\u0427\u0442\u043e \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u2014 \u00ab\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043a\u043e\u0434\u00bb? \u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0439\u0442\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>ngOnChanges<\/code> \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0436\u0435. \u042d\u0442\u043e \u043f\u043b\u043e\u0445\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0430\u0439\u0434-\u044d\u0444\u0444\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u0435\u043d, \u043f\u043e \u0441\u0443\u0442\u0438, \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0434\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.&nbsp;<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442\u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043d\u043f\u0443\u0442\u0430 \u2014 <em>\u0441\u0435\u0442\u0442\u0435\u0440 <\/em>\u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u044f\u043c\u043e\u043b\u0438\u043d\u0435\u0439\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c \u0447\u0442\u043e \u0435\u0433\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c\u044b\u043c <em>\u0433\u0435\u0442\u0442\u0435\u0440\u043e\u043c<\/em>.<\/p>\n<p>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u2014 \u0442\u0435\u043c\u0430 \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0434\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u0441\u043a\u043e\u0440\u0435 \u0434\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f. \u0410 \u043f\u043e\u043a\u0430 \u0432\u043e\u0437\u044c\u043c\u0438\u0442\u0435 \u0437\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0433\u0435\u0442\u0442\u0435\u0440\u043e\u0432. \u042d\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f, \u0447\u0435\u043c \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u043a\u0430 \u0438\u043b\u0438 \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435\u0441\u044c \u0442\u0435\u0445\u043d\u0438\u043a\u043e\u0439 \u043c\u0435\u043c\u043e\u0438\u0437\u0430\u0446\u0438\u0438 \u2014 \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0447\u0438\u0441\u0442\u044b\u043c \u043f\u0430\u0439\u043f\u043e\u043c.<\/p>\n<p><iframe id=\"5f5f52985e0ed38aa206cf92\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f52985e0ed38aa206cf92\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<p>\u042d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0441\u0435\u0442\u0442\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043e\u043f\u0443\u0441\u0442\u0438\u043b \u0434\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438, \u043d\u043e \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043d\u0435 \u043d\u0430\u043f\u043e\u043c\u043d\u0438\u043b \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c.<\/p>\n<h3>Template reference variables<\/h3>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0432 Angular \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 <code>@ViewChild<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u043e\u043d \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435:<\/p>\n<pre><code class=\"htmlmixed\">&lt;input #input&gt; &lt;button (click)=\"onClick(input)\"&gt;Focus&lt;\/button&gt;<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c <em>template reference variable<\/em> \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u043c\u0435\u0442\u043e\u0434, \u0433\u0434\u0435 \u043e\u043d\u0430 \u043d\u0443\u0436\u043d\u0430. \u0422\u0430\u043a \u043a\u043e\u0434 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0447\u0438\u0449\u0435. \u0414\u0443\u043c\u0430\u0439\u0442\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u043a\u0430\u043a \u043e \u043f\u043e\u0434\u043e\u0431\u0438\u0438 <em>\u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f<\/em> \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435.&nbsp;<\/p>\n<p>\u041d\u043e \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c DOM-\u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c? \u041c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>@ViewChild(MyComponent, {read: ElementRef})<\/code>, \u043d\u043e \u043c\u044b \u043e\u0431\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u0431\u0435\u0437 \u043f\u043e\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u0435\u0441\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0443 \u0441 <code>exportAs<\/code>:<\/p>\n<p><iframe id=\"5f5f52f09b5e7f8ac67b3793\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f52f09b5e7f8ac67b3793\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">@Directive({     selector: '[element]',     exportAs: 'elementRef', }) export class ElementDirective&lt;T extends Element&gt; extends ElementRef&lt;T&gt; {     constructor(@Inject(ElementRef) {nativeElement}: ElementRef&lt;T&gt;) {         super(nativeElement);     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442<\/h3>\n<p>\u041b\u044e\u0434\u0438 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <code>ComponentFactoryResolver<\/code> \u0434\u043b\u044f \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u0417\u0430\u0447\u0435\u043c, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0430 <code>ngComponentOutlet<\/code>? \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0430\u043a \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438 \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u043d\u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435. \u0425\u043e\u0440\u043e\u0448\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u043e\u043f\u044f\u0442\u044c \u0436\u0435, <strong>Dependency Injection<\/strong>. <code>ngComponentOutlet<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c <code>Injector<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438 \u043f\u043e\u0434\u043b\u043e\u0436\u0438\u043c \u0432 \u043d\u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u043a\u0435\u043d.<\/p>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438, \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c <em>\u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f<\/em>, <em>\u0448\u0430\u0431\u043b\u043e\u043d\u044b<\/em> \u0438 <em>\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/em>. \u0418 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043d\u0435\u0442. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c <strong>\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/strong> \u0438 \u0435\u0441\u0442\u044c \u0435\u0433\u043e <strong>\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/strong>.<\/p>\n<p><iframe id=\"5f5f531b42448d8ae05d2747\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f531b42448d8ae05d2747\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<p>\u041c\u044b \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434, \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0438\u0439 \u043e\u0442 \u0442\u0438\u043f\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041c\u044b \u0432\u044b\u043d\u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0432 \u043a\u0440\u043e\u0448\u0435\u0447\u043d\u0443\u044e open-source-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/github.com\/TinkoffCreditSystems\/ng-polymorpheus\" rel=\"noopener noreferrer nofollow\"><u>ng-polymorpheus.<\/u><\/a> \u041e\u043d\u0430 \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, <code>ngTemplateOutlet<\/code>, <code>ngContentOutlet<\/code> \u0438\u043b\u0438 \u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044e \u0441 \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u044b\u043a\u0430\u0435\u0448\u044c \u043a \u0442\u0430\u043a\u043e\u043c\u0443, \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0434\u043e\u0440\u043e\u0433\u0438 \u0443\u0436\u0435 \u043d\u0435\u0442! \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0447\u0438\u0442\u0430\u0439\u0442\u0435 <a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/473108\/\" rel=\"noopener noreferrer nofollow\"><u>\u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/u><\/a><\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043c\u043e\u0438 \u0441\u043e\u0432\u0435\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0432\u0430\u043c \u043f\u043e\u043b\u0435\u0437\u043d\u044b. \u041f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0438\u043d\u0433\u0430!<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/519052\/\"> https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/519052\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/519052\/\">\n<p>\u042d\u0442\u0438\u043c \u043b\u0435\u0442\u043e\u043c \u043c\u044b \u0441 <a href=\"https:\/\/habr.com\/ru\/users\/MarsiBarsi\/\" rel=\"noopener noreferrer nofollow\"><u>\u0420\u043e\u043c\u043e\u0439<\/u><\/a> \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0441\u0435\u0440\u0438\u044e \u0442\u0432\u0438\u0442\u043e\u0432 \u0441 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u0441\u043e\u0432\u0435\u0442\u0430\u043c\u0438 \u0438 \u043f\u0440\u0438\u0435\u043c\u0430\u043c\u0438 \u043f\u043e Angular. \u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e \u0442\u0435\u043f\u043b\u043e \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u043e \u044d\u0442\u0443 \u0438\u043d\u0438\u0446\u0438\u0430\u0442\u0438\u0432\u0443, \u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0431\u043e\u0431\u0449\u0430\u044e\u0449\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e.  \u0412\u043e\u0442 \u043c\u043e\u0438 5 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438. \u042d\u0442\u0438 \u0441\u043e\u0432\u0435\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438\u0437 <a href=\"https:\/\/twitter.com\/Waterplea\" rel=\"noopener noreferrer nofollow\"><u>\u043c\u043e\u0435\u0433\u043e \u0442\u0432\u0438\u0442\u0442\u0435\u0440\u0430<\/u><\/a>. \u041e\u043d\u0438 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0432\u0430\u043c \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u043d\u0430\u0432\u044b\u043a\u0438 \u0438\u043b\u0438 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0434\u0430\u0434\u0443\u0442 \u043f\u0430\u0440\u0443 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u0435\u043c\u043e\u0432.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>1. \u0420\u0430\u0437\u0431\u0435\u0440\u0438\u0442\u0435\u0441\u044c \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439<\/h2>\n<p>\u0412 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0445 \u0443\u0433\u043b\u0443\u0431\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 Angular. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/habr.com\/ru\/post\/327004\/\" rel=\"noopener noreferrer nofollow\"><u>\u0432\u043e\u0442 \u044d\u0442\u0430.<\/u><\/a> \u0422\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0441\u0432\u0435\u0436\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u044b \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043e\u0432\u0435\u0442\u0430\u043c.<\/p>\n<h3>\u041e\u0441\u043d\u043e\u0432\u044b<\/h3>\n<p>\u0412 Angular \u0434\u0432\u0430 \u0440\u0435\u0436\u0438\u043c\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439: <code>Default<\/code> \u0438 <code>OnPush<\/code>. \u041f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 <em><strong>tick<\/strong><\/em> \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u0438\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <em>Zone.js<\/em>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0430\u0442\u0447\u0438\u0442 \u0432\u0441\u0435 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0440\u043e\u0434\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u043f\u0440\u043e\u043c\u0438\u0441\u043e\u0432. \u0412\u0442\u043e\u0440\u043e\u0439 \u0440\u0435\u0436\u0438\u043c \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u0442 view \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0432 \u043d\u0435\u043c \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u043b\u0443\u0448\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<h3>Default vs OnPush<\/h3>\n<p>\u041f\u043e \u043f\u0440\u0430\u0432\u0434\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u0432\u0440\u044f\u0434 \u043b\u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c <code>Default<\/code>. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0438\u0448\u0438\u0442\u0435 \u043a\u043e\u0434 \u0442\u0430\u043a, \u043a\u0430\u043a \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0438 \u0432\u044b \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0435\u0442\u0435 \u0432 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u0441 <code>OnPush<\/code>. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 <strong>\u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043c\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435<\/strong>. \u0415\u0441\u043b\u0438 \u0432\u0430\u0448\u0438 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0438\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u043d\u0435\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435, <code>OnPush<\/code> \u043f\u043e\u0434\u0446\u0435\u043f\u0438\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442 \u0432\u044c\u044e.<\/p>\n<p>\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0447\u0435\u0440\u0435\u0437 <code>@HostListener<\/code> Angular \u0437\u0430\u043c\u0435\u0442\u0438\u0442 \u0438 \u0432 <code>OnPush<\/code>. \u041d\u043e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 RxJS? \u0412\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u044c <code>ChangeDetectorRef<\/code> \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>markForCheck()<\/code>, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u0414\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 <code>async<\/code> \u043f\u0430\u0439\u043f, \u0435\u0441\u043b\u0438 \u0441\u0442\u0440\u0438\u043c \u0432 \u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430. \u041e\u043d \u0441\u0430\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438 \u0432\u043e\u0437\u044c\u043c\u0435\u0442 \u043d\u0430 \u0441\u0435\u0431\u044f \u043e\u0442\u043f\u0438\u0441\u043a\u0443.&nbsp;<\/p>\n<p>\u0412\u0430\u043c \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d:<\/p>\n<pre><code class=\"htmlmixed\">&lt;div *ngIf=\"stream$ | async as result\"&gt; &nbsp;&nbsp;&nbsp;&nbsp;\u2026 &lt;\/div&gt;<\/code><\/pre>\n<p>\u041d\u043e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0432\u0430\u0436\u043d\u044b \u0442\u0430\u043a\u0436\u0435 <strong>falsy<\/strong>-\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b? \u041c\u043e\u0436\u043d\u043e \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u044c \u0432\u0441\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0438\u0437 ngIf \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0443. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044c\u044e:<\/p>\n<p><iframe id=\"5f5f571d5e0ed38aa206cf93\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f571d5e0ed38aa206cf93\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">@Directive({   selector: \"[ngLet]\" }) export class LetDirective&lt;T&gt; {   @Input()   ngLet: T;    constructor(     @Inject(ViewContainerRef) container: ViewContainerRef,     @Inject(TemplateRef) templateRef: TemplateRef&lt;LetContext&lt;T&gt;&gt;   ) {     container.createEmbeddedView(templateRef, new LetContext&lt;T&gt;(this));   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>NgZone<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043d\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 <code>OnPush<\/code>, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438. \u0417\u0430\u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u0435 <code>NgZone<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0439\u0442\u0435 \u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 <code>.runOutsideAngular()<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0445 \u0442\u0438\u043a\u043e\u0432 \u0432 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u0414\u0430\u0436\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <code>Default<\/code> \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u044d\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u042d\u0442\u043e \u0443\u043c\u0435\u0441\u0442\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f \u0447\u0430\u0441\u0442\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a <code>mousemove<\/code> \u0438\u043b\u0438 <code>scroll<\/code>. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u0432 RxJS-\u0441\u0442\u0440\u0438\u043c\u0430\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0432\u0443\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432: \u043e\u0434\u0438\u043d \u2014 \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0437\u043e\u043d\u044b, \u0434\u0440\u0443\u0433\u043e\u0439 \u2014 \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0432 \u043d\u0435\u0435, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439:<\/p>\n<p><iframe id=\"5f5f573b5f535f8ab4ec3d77\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f573b5f535f8ab4ec3d77\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">class ZonefreeOperator&lt;T&gt; implements Operator&lt;T, T&gt; {   constructor(private readonly zone: NgZone) {}    call(observer: Observer&lt;T&gt;, source: Observable&lt;T&gt;): TeardownLogic {     return this.zone.runOutsideAngular(       () =&gt; source.subscribe(observer)     );   } }  export function zonefull&lt;T&gt;(zone: NgZone): MonoTypeOperatorFunction&lt;T&gt; {   return map(value =&gt; zone.run(() =&gt; value)); }  export function zonefree&lt;T&gt;(zone: NgZone): MonoTypeOperatorFunction&lt;T&gt; {   return source =&gt; source.lift(new ZonefreeOperator(zone)); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<blockquote>\n<p><em>\u0415\u0449\u0435 \u043e\u0434\u0438\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0441 <\/em><code>@HostListener<\/code><em>, \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <\/em><code>EventManagerPlugin<\/code><em>. \u041c\u044b \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u043b\u0438 open-source-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <\/em><a href=\"https:\/\/github.com\/TinkoffCreditSystems\/ng-event-plugins\" rel=\"noopener noreferrer nofollow\"><em><u>ng-event-plugins.<\/u><\/em><\/a><em> \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u0441\u0435\u0438\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u0447\u0438\u0442\u0430\u0439\u0442\u0435 <\/em><a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/492766\/\" rel=\"noopener noreferrer nofollow\"><em><u>\u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/u><\/em><\/a><\/p>\n<\/blockquote>\n<h2>2. \u0425\u043e\u0440\u043e\u0448\u0435\u043d\u044c\u043a\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0438\u0442\u0435\u0441\u044c \u0432 RxJS<\/h2>\n<p>RxJS \u2014 \u043e\u0447\u0435\u043d\u044c \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442. \u041c\u044b \u0432\u0441\u0435 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 \u0442\u043e\u0439 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u043c\u0435\u0440\u0435, \u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u0435\u0435 \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u0438\u043c \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e<strong> <\/strong>\u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c. \u041e\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u0442\u0440\u0438\u043c\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u2014&nbsp;<\/p>\n<p><iframe id=\"5f5f4f7699fe6819269a176b\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f4f7699fe6819269a176b\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<p>\u2014 \u0434\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0443 \u0432\u0430\u0441 \u0441\u043a\u0440\u043e\u043b\u043b \u0438\u043b\u0438 \u0438\u043d\u0435\u0440\u0446\u0438\u043e\u043d\u043d\u044b\u0439:<\/p>\n<p><iframe id=\"5f5f4fde1958dd1942e0e6de\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f4fde1958dd1942e0e6de\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435, \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0448\u0430\u043f\u043a\u0443, \u0438\u0441\u0447\u0435\u0437\u0430\u044e\u0449\u0443\u044e \u043f\u0440\u0438 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0435 \u0441\u0430\u0439\u0442\u0430 \u0432\u043d\u0438\u0437. \u0421\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e CSS \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 RxJS:<\/p>\n<p><iframe id=\"5f5f4feae3f603193557f2df\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f4feae3f603193557f2df\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">@Directive({   selector: \"[sticky]\",   providers: [DestroyService] }) export class StickyDirective {   constructor(     @Inject(DestroyService) destroy$: Observable&lt;void&gt;,     @Inject(WINDOW) windowRef: Window,     renderer: Renderer2,     { nativeElement }: ElementRef&lt;HTMLElement&gt;   ) {     fromEvent(windowRef, \"scroll\")       .pipe(         map(() =&gt; windowRef.scrollY),         pairwise(),         map(([prev, next]) =&gt; next &lt; THRESHOLD || prev &gt; next),         distinctUntilChanged(),         startWith(true),         takeUntil(destroy$)       )       .subscribe(stuck =&gt; {         renderer.setAttribute(           nativeElement,            \"data-stuck\",            String(stuck)         );       });   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043b\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u0446\u0435\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u043d\u0438\u0435 RxJS \u0434\u043b\u044f Angular-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0432 \u0434\u043e\u043b\u0433\u043e\u0441\u0440\u043e\u0447\u043d\u043e\u0439 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0435. \u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 RxJS \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0435\u043a\u043e\u0435\u0433\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u044b, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u043c\u044b\u0441\u043b\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438. \u041d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u0442\u0435, \u0432\u0430\u0448 \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u0435\u0442 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u0435\u0435 \u0438 \u043b\u0435\u0433\u0447\u0435 \u0432 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435.<\/p>\n<p>\u0422\u0443\u0442 \u043e\u0441\u043e\u0431\u043e \u043d\u0435\u0447\u0435\u0433\u043e \u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u0442\u044c, \u043a\u0440\u043e\u043c\u0435 \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0432\u0430\u0442\u044c\u0441\u044f . \u0415\u0441\u043b\u0438 \u0432\u0438\u0434\u0438\u0442\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 RxJS, \u2014 \u043f\u043e\u043f\u044b\u0442\u0430\u0439\u0442\u0435\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e. \u0418\u0437\u0431\u0435\u0433\u0430\u0439\u0442\u0435 \u0441\u0430\u0439\u0434-\u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a. \u0414\u0435\u0440\u0436\u0438\u0442\u0435 \u0441\u0432\u043e\u0438 \u0441\u0442\u0440\u0438\u043c\u044b \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0438 \u0441\u043b\u0435\u0434\u0438\u0442\u0435 \u0437\u0430 \u0443\u0442\u0435\u0447\u043a\u0430\u043c\u0438 \u043f\u0430\u043c\u044f\u0442\u0438 (\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u0434\u0430\u043b\u044c\u0448\u0435).<\/p>\n<h2>3. \u0412\u044b\u0436\u0438\u043c\u0430\u0439\u0442\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0438\u0437 TypeScript<\/h2>\n<p>\u041c\u044b \u0432\u0441\u0435 \u043f\u0438\u0448\u0435\u043c Angular-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 TypeScript. \u041d\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u043b\u044c\u0437\u0443, \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u042f \u0440\u0435\u0434\u043a\u043e \u0432\u0438\u0436\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0441 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c <code>strict: true<\/code>. \u0412\u0430\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e. \u041e\u043d\u043e \u0441\u043f\u0430\u0441\u0435\u0442 \u0432\u0430\u0441 \u043e\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 <em>cannot read property of null<\/em> \u0438 <em>undefined is not a function<\/em>.<\/p>\n<h3>\u0414\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438<\/h3>\n<p>\u0412 TypeScript \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438 \u2014 \u0434\u043b\u044f \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u0442\u0438\u043f, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c, \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d. \u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u043e\u0432, \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043e\u043a \u0438 \u0441\u0443\u0436\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0430\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0440\u0443\u0442\u043e\u0439 API. \u041f\u043e\u0447\u0442\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u0439\u043f\u043a\u0430\u0441\u0442. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e RxJS-\u043c\u0435\u0442\u043e\u0434\u0430 <code>fromEvent<\/code>:<\/p>\n<p><iframe id=\"5f5f506f5f535f8ab4ec3d76\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f506f5f535f8ab4ec3d76\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">\/\/ \u0422\u0438\u043f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c currentTarget export type EventWith&lt;   E extends Event,   T extends FromEventTarget&lt;E&gt; &gt; = E &amp; {   readonly currentTarget: T; };  \/\/ \u0422\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 fromEvent export function typedFromEvent&lt;   E extends keyof GlobalEventHandlersEventMap,   T extends FromEventTarget&lt;EventWith&lt;GlobalEventHandlersEventMap[E], T&gt;&gt; &gt;(   target: T,   event: E,   options: AddEventListenerOptions = {}, ): Observable&lt;EventWith&lt;GlobalEventHandlersEventMap[E], T&gt;&gt; {   return fromEvent(target, event, options); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421 \u043d\u0438\u043c \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438\u043c\u0435\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0442\u0438\u043f, \u0430 <code>currentTarget<\/code> \u2014 \u044d\u0442\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b \u0435\u0433\u043e \u0441\u043b\u0443\u0448\u0430\u0435\u0442\u0435.<\/p>\n<blockquote>\n<p><em>API, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0430\u0445, \u0445\u043e\u0440\u043e\u0448\u0438 \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0435 \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u044b \u043d\u0430 \u0444\u043e\u0440\u043c\u0430\u0442 \u0434\u0430\u043d\u043d\u044b\u0445. \u0410 \u0437\u043d\u0430\u0447\u0438\u0442, \u0438\u0445 \u043b\u0435\u0433\u043a\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/em><\/p>\n<\/blockquote>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u043c\u0430\u043b\u043e \u0441\u0442\u0430\u0442\u0435\u0439 \u043e \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0439 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0432\u0441\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0442\u0440\u044e\u043a\u0430\u0445 \u0441 TypeScript. \u042f \u043e\u0447\u0435\u043d\u044c \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u0437\u043d\u0430\u043d\u0438\u044f \u0432 \u044d\u0442\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u043a\u043e\u0434. \u041c\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u043e\u0432\u0435\u0442: \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>any<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a, \u0431\u043e\u043b\u0435\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 <code>unknown<\/code>.<\/p>\n<h3>\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b<\/h3>\n<p>\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b TypeScript, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b. \u041f\u0440\u0438 \u0443\u043c\u0435\u043b\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0432\u0430\u0448 \u043a\u043e\u0434. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0431\u044b\u0432\u0430\u044e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u0442\u0438\u043f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439, \u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442: \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438\u043b\u0438 \u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430, \u0445\u043e\u0442\u044f \u0442\u0438\u043f \u0438 \u0442\u0430\u043c, \u0438 \u0442\u0430\u043c \u2014 <code>number<\/code>. TypeScript \u0442\u0430\u043a\u043e\u0435 \u043d\u0435 \u043e\u0442\u043b\u043e\u0432\u0438\u0442, \u043d\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 runtime \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430:<\/p>\n<p><iframe id=\"5f5f50ba1958dd1942e0e6df\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f50ba1958dd1942e0e6df\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">export function assert&lt;T, K extends keyof T&gt;(   assertion: (input: T[K]) =&gt; boolean,   messsage: string ): PropertyDecorator {   return (target, key) =&gt; {     Object.defineProperty(target, key, {       set(this: T, initialValue: T[K]) {         let currentValue = initialValue;          Object.defineProperty(this, key, {           get(): T[K] {             return currentValue;           },           set(this: T, value: T[K]) {             console.assert(assertion(value), messsage);             currentValue = value;           }         });       }     });   }; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b \u0437\u043d\u0430\u043b\u0438, \u0447\u0442\u043e \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 <code>super()<\/code>? Angular \u0441\u0430\u043c \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e \u0437\u0430 \u0432\u0430\u0441, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0435:<\/p>\n<p><iframe id=\"5f5f50e146103f8a958c9665\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f50e146103f8a958c9665\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<p>\u0415\u0449\u0435 \u043e\u0434\u0438\u043d \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u2014 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043a\u0443\u0441\u043e\u043a \u043a\u043e\u0434\u0430 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f Web Audio API \u0432 Angular, \u0433\u0434\u0435 \u043c\u044b <a href=\"https:\/\/github.com\/ng-web-apis\/audio\/blob\/c7db781a31d9a945700b0f6bce055bd66d0d4810\/projects\/audio\/src\/utils\/process-audio-param.ts\" rel=\"noopener noreferrer nofollow\"><u>\u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0431\u0430\u0439\u043d\u0434\u0438\u043d\u0433 \u0432 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b<\/u><\/a> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/github.com\/ng-web-apis\/audio\/blob\/master\/projects\/audio\/src\/decorators\/audio-param.ts\" rel=\"noopener noreferrer nofollow\"><u>\u0441\u0442\u0440\u043e\u0433\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430.<\/u><\/a> \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0441\u0430\u043c\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/493622\/\" rel=\"noopener noreferrer nofollow\"><u>\u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0442\u0443\u0442.<\/u><\/a><\/p>\n<h2>4. Dependency Injection. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0435\u0433\u043e \u043f\u043e\u0447\u0430\u0449\u0435<\/h2>\n<p>DI \u2014 \u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u0438\u0447\u0438\u043d, \u043f\u043e\u0447\u0435\u043c\u0443 Angular \u0442\u0430\u043a\u043e\u0439 \u043c\u043e\u0449\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0434\u0430\u0436\u0435 \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u0430. \u041d\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0447\u0430\u0441\u0442\u043e \u0435\u0433\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u043e \u043f\u043e\u043b\u043d\u043e\u0439.<\/p>\n<blockquote>\n<p><em>\u041c\u043e\u0433\u0443 \u043f\u043e\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u0442\u044c <\/em><a href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/516622\/\" rel=\"noopener noreferrer nofollow\"><em><u>\u043d\u0430\u0448\u0443 \u0441\u0442\u0430\u0442\u044c\u044e, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u0443\u044e DI<\/u><\/em><\/a><em>, \u0447\u0442\u043e\u0431\u044b \u043e\u0441\u0432\u043e\u0438\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c.<\/em><\/p>\n<\/blockquote>\n<h3>RxJS<\/h3>\n<p>\u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u043e\u0432\u0435\u0442\u043e\u0432, \u0432\u044b\u0448\u0435 \u044f \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0431\u044b\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a \u0443\u0442\u0435\u0447\u043a\u0430\u043c \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 RxJS. \u0413\u043b\u0430\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e, <strong>\u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u0441\u0442\u0440\u0438\u043c \u0440\u0443\u043a\u0430\u043c\u0438, \u0432\u0430\u043c \u0436\u0435 \u0438 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043e\u0442 \u043d\u0435\u0433\u043e \u043e\u0442\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f<\/strong>. \u0418\u0434\u0438\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 Angular \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432 \u0441\u0435\u0440\u0432\u0438\u0441:<\/p>\n<p><iframe id=\"5f5f512099fe6819269a176c\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f512099fe6819269a176c\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">@Injectable() export class DestroyService extends Subject&lt;void&gt; implements OnDestroy {     ngOnDestroy() {         this.next();         this.complete();     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u0449\u0438\u0435 \u0441\u0442\u0440\u0438\u043c\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u0432 DI. \u041d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u043d\u0430 \u0431\u0430\u0437\u0435 <code>requestAnimationFrame<\/code> \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0442\u043e\u043a\u0435\u043d \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0435\u0433\u043e. \u0412\u044b \u0434\u0430\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043b\u043e\u0436\u0438\u0442\u044c \u0432 \u043d\u0435\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0437\u043e\u043d\u044b, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435:<\/p>\n<p><iframe id=\"5f5f51379a7d1419651d09b5\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f51379a7d1419651d09b5\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<h3>\u0422\u043e\u043a\u0435\u043d\u044b<\/h3>\n<p>DI \u2014 \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442\u0435 \u043e\u0442 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432\u0440\u043e\u0434\u0435 <code>window<\/code> \u0438\u043b\u0438 <code>navigator<\/code> \u2014 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043e \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Angular Universal \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438. \u0422\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0435 \u0435\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438. \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0431\u0435\u0437 \u0442\u0440\u0443\u0434\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u0442\u043e\u043a\u0435\u043d\u044b. \u0412\u043d\u0443\u0442\u0440\u0438 \u0444\u0430\u0431\u0440\u0438\u043a\u0438 \u043f\u0440\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0436\u0435\u043a\u0442\u043e\u0440. \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u043e \u043f\u0430\u0440\u0430 \u0441\u0442\u0440\u043e\u043a \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <code>WINDOW<\/code> \u0442\u043e\u043a\u0435\u043d\u0430 \u043d\u0430 \u0431\u0430\u0437\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e <code>DOCUMENT<\/code>:<\/p>\n<p><iframe id=\"5f5f51ad99fe6819269a176d\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5f5f51ad99fe6819269a176d\" class=\"embed_video embed__content\"><\/iframe><\/p>\n<details class=\"spoiler\">\n<summary><\/summary>\n<\/details>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-309903","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/309903","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=309903"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/309903\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=309903"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=309903"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=309903"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}