{"id":280642,"date":"2016-11-08T20:00:05","date_gmt":"2016-11-08T17:00:05","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=280642"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=280642","title":{"rendered":"Knockout vs React: \u0443 \u0432\u0441\u0435\u0445 \u0441\u0432\u043e\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/dff\/21e\/94b\/dff21e94bebc401abf3d185722678da4.png\"\/><br \/>  <i>\u0410\u0432\u0442\u043e\u0440: \u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u041a\u043b\u0438\u043c\u0435\u043d\u043a\u043e, Senior Developer, DataArt<\/i><\/p>\n<p>  \u041e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0430\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043b\u0438\u0448\u044c JavaScript \u0438 jQuery \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u043d\u043e\u0433\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u2014 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043b\u043e\u0445\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u0441\u043f\u0430\u0433\u0435\u0442\u0442\u0438-\u043a\u043e\u0434, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u0441\u043a\u0440\u044b\u0442\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0438 \u0441 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438, \u043a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435, \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0435\u0444\u0435\u043a\u0442\u043e\u0432.<\/p>\n<p>  \u0414\u043b\u044f \u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043f\u0440\u0438\u0447\u0435\u043c \u043f\u043e\u0434\u0447\u0430\u0441 \u0442\u0440\u0443\u0434\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0438\u0437 \u043d\u0438\u0445 \u043b\u0443\u0447\u0448\u0435. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0434\u0432\u0443\u0445 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432: Knockout, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e MVVM-\u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u0438 React, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u043e\u0442 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442. <\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0449\u0443\u044e \u043c\u0443\u0437\u044b\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f, \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0436\u0430\u043d\u0440\u0430\u043c, \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0430\u043c, \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f\u043c, \u0441\u0431\u043e\u0440\u043d\u0438\u043a\u0430\u043c \u0438 \u0440\u0430\u0434\u0438\u043e\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c.<a name=\"habracut\"><\/a><\/p>\n<p>  \u0412\u043e\u0442 \u043a\u0430\u043a \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/bcb\/c90\/24e\/bcbc9024ea8a4163b1a6f4cc1ceb604f.png\"\/><\/p>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e. \u0412 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u044b, \u0430 \u0432 \u043d\u0438\u0436\u043d\u0435\u0439 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u0421\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c. \u0421\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u043c \u043a\u043e\u0434\u0435 (\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 ASP.Net Web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043a\u0440\u0438\u043f\u0442 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0441 <a href=\"https:\/\/github.com\/yugklim\/KnockoutVsReact\">GitHub<\/a>).<\/p>\n<h2>1. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441 Knockout<\/h2>\n<p>  \u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (MusicViaKnockout\\Index.cshtml) \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0434\u043b\u044f Knockout \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u2014 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0430 \u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 (data-bind) DOM-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043a view-\u043c\u043e\u0434\u0435\u043b\u0438:  <\/p>\n<pre><code class=\"javascript\">&lt;div&gt;     &lt;div class=&quot;genres&quot;&gt;         &lt;div style=&quot;font-weight: bold&quot;&gt;Genres:&lt;\/div&gt;         &lt;div data-bind=&quot;foreach: genres&quot;&gt;             &lt;div&gt; &lt;input type=&quot;checkbox&quot; data-bind=&quot;value: GenreID, checked: $root.genresFound, event: {change: genresChanged}&quot;&gt;                 &lt;span class=&quot;js-genres&quot; data-bind=&quot;text: Genre&quot;&gt;&lt;\/span&gt;             &lt;\/div&gt;         &lt;\/div&gt;     &lt;\/div&gt;     &lt;div class=&quot;selects&quot;&gt;         &lt;div&gt;             &lt;label&gt;Performers:&lt;\/label&gt; &lt;select data-bind=&quot;options: performers, optionsText: 'Performer', optionsValue: 'PerformerID'&quot;&gt;&lt;\/select&gt;         &lt;\/div&gt;         &lt;div&gt;             &lt;label&gt;Composers:&lt;\/label&gt; &lt;select data-bind=&quot;options: composers, optionsText: 'Composer', optionsValue: 'ComposerID'&quot;&gt;&lt;\/select&gt;         &lt;\/div&gt;         &lt;div&gt;             &lt;label&gt;Albums:&lt;\/label&gt; &lt;select data-bind=&quot;options: albums, optionsText: 'Album', optionsValue: 'AlbumID'&quot;&gt;&lt;\/select&gt;         &lt;\/div&gt;         &lt;div&gt;             &lt;label style=&quot;clear: both&quot;&gt;Casts:&lt;\/label&gt; &lt;select data-bind=&quot;options: casts, optionsText: 'Cast', optionsValue: 'CastID'&quot;&gt;&lt;\/select&gt;         &lt;\/div&gt;     &lt;\/div&gt; &lt;\/div&gt; &lt;div class=&quot;musicContainer&quot;&gt;     &lt;div class=&quot;musics&quot;&gt;         &lt;label&gt;Musics:&lt;\/label&gt;&lt;br \/&gt;         &lt;div style=&quot;overflow-y: scroll; height: 500px&quot;&gt;             &lt;table data-bind=&quot;foreach: musics&quot;&gt;                 &lt;tr&gt;                     &lt;td&gt;                         &lt;div data-bind=&quot;text: Music&quot;&gt;&lt;\/div&gt;                     &lt;\/td&gt;                 &lt;\/tr&gt;             &lt;\/table&gt;         &lt;\/div&gt;     &lt;\/div&gt; &lt;\/div&gt; <\/code><\/pre>\n<p>  \u0410 \u0432\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 view-\u043c\u043e\u0434\u0435\u043b\u044c:  <\/p>\n<pre><code class=\"javascript\">$(function() {      var musicViewModel = {         genres: ko.observableArray(),         genresFound: ko.observableArray(),         performers: ko.observableArray(),         composers: ko.observableArray(),         albums: ko.observableArray(),         casts: ko.observableArray(),         musics: ko.observableArray()     };      mapServerData = function(data) {         if (!data) return;         musicViewModel.genres(data.Filters.Genres);         musicViewModel.genresFound(data.Filters.GenresFound);         musicViewModel.performers( data.Filters.Performers);         musicViewModel.performers.unshift({PerformerID: -1, Performer: 'All'});         musicViewModel.composers(data.Filters.Composers);         musicViewModel.composers.unshift({ComposerID: -1, Composer: 'All'});         musicViewModel.albums(data.Filters.Albums);         musicViewModel.albums.unshift({AlbumID: -1, Album: 'All'});         musicViewModel.casts(data.Filters.Casts);         musicViewModel.casts.unshift({CastID: -1, Cast: 'All'});         musicViewModel.musics(data.Filters.Musics);     },      genresChanged = function (data, event) {         $.ajax({             url: &quot;\/Music\/FilterMusics&quot;,             type: &quot;GET&quot;,             data: {                 genreIDs: ko.toJS(musicViewModel.genresFound),                 &quot;composerID&quot;: null,                 &quot;albumID&quot;: null,                 &quot;performerID&quot;: null,                 &quot;castID&quot;: null             },             traditional: true,             timeout: 30000,             success: function (data) {                 mapServerData(data);             }         });     }      $.getJSON(&quot;\/api\/MusicWebAPI&quot;, function (data) {         mapServerData(data);         ko.applyBindings(musicViewModel);     }); }); <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 Knockout, \u0432\u0441\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e. \u041f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u044b\u0437\u043e\u0432\u043e\u043c $.getJSON(&quot;\/api\/MusicWebAPI&quot;), \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043e\u043d\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a view-\u043c\u043e\u0434\u0435\u043b\u0438. \u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0431\u0435\u0440\u0435\u0442 \u043d\u0430 \u0441\u0435\u0431\u044f. \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u0438 \u043a\u043e\u0434, \u0438 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0430 \u043f\u0440\u043e\u0441\u0442\u044b \u0438 \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u044b. \u042d\u0442\u043e \u2014 \u043d\u0435\u043e\u0441\u043f\u043e\u0440\u0438\u043c\u043e\u0435 \u0434\u043e\u0441\u0442\u043e\u0438\u043d\u0441\u0442\u0432\u043e Knockout.<\/p>\n<h2>2. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 React <\/h2>\n<p>  \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 (..\/Views\/Music\/Index.cshtml):  <\/p>\n<pre><code class=\"javascript\">@using MusicChoice2.HtmlHelpers @using Newtonsoft.Json @using React.Web.Mvc @model MusicChoice.ViewModels.MusicViewModel  @{     ViewBag.Title = &quot;title&quot;; }  &lt;script src=&quot;@Url.Content(&quot;~\/Scripts\/jquery.min.js&quot;)&quot;&gt;&lt;\/script&gt; &lt;script src=&quot;@Url.Content(&quot;~\/Scripts\/underscore-min.js&quot;)&quot;&gt;&lt;\/script&gt; &lt;script src=&quot;@Url.Content(&quot;~\/Scripts\/react.js&quot;)&quot;&gt;&lt;\/script&gt; &lt;script src=&quot;@Url.Content(&quot;~\/Scripts\/react-dom.js&quot;)&quot;&gt;&lt;\/script&gt; &lt;script src=&quot;@Url.Content(&quot;~\/Scripts\/MusicChoice\/MusicFilters.jsx&quot;)&quot;&gt;&lt;\/script&gt; &lt;script src=&quot;@Url.Content(&quot;~\/Scripts\/MusicChoice\/MusicChoice.js&quot;)&quot;&gt;&lt;\/script&gt; &lt;link rel=&quot;stylesheet&quot; href=&quot;..\/..\/Styles\/music.css&quot;&gt;  &lt;div&gt;     @Html.React(&quot;MusicFilters&quot;, new     {         albums = Model.Filters.Albums,         casts = Model.Filters.Casts,         composers = Model.Filters.Composers,         genres = Model.Filters.Genres,         performers = Model.Filters.Performers,         genresFound = Model.Filters.GenresFound,         musics = Model.Filters.Musics,         albumID = Model.Filters.AlbumID,         castID = Model.Filters.CastID,         composerID = Model.Filters.ComposerID,         performerID = Model.Filters.PerformerID,          onFilterChanged = &quot;music.onFilterChanged&quot;     },      &quot;containerId&quot;)          @Html.ReactInitJavaScriptAndAssignIds(new[] { &quot;music.filters&quot; }) &lt;\/div&gt; <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u2014 MVC helper (@Html.React(\u00abMusicFilters\u00bb\u2026 ), \u043d\u0430\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0430\u043c React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">var MusicFilters = React.createClass({     getDefaultProps: function() {         return {             defaultLoadParameters : {}         }     },      getInitialState: function() {         return {               performers: this.props.performers             , genres: this.props.genres             , genresFound: this.props.genresFound             , musics: this.props.musics             , albums: this.props.albums             , composers: this.props.composers             , casts: this.props.casts             , selected: {                   performerID: this.props.performerID                 , musicID: this.props.musicID                 , albumID: this.props.albumID                 , composerID: this.props.composerID                 , castID: this.props.castID             }         }     },      render: function() {         var onFilterChanged = this.onFilterChanged;         var musicFilters = this;         var genresContains = function(genreID) {             var contains = false;             musicFilters.state.genresFound.forEach(function (g) {                 if (g == genreID) {                     contains = true;                 }             });             return contains;         };         var onGenreChanged = this.onGenreChanged;          var renderDropDown = function(title, id, values, selectedValue, optionIndex, optionValue, selectedParameter, labelStyle) {             return  (values !== undefined && values !== null)? &lt;div&gt;                 &lt;label style={labelStyle}&gt;{title + ':'}&lt;\/label&gt;                 &lt;select id={id} value={selectedValue || -1} onChange={onFilterChanged.bind(musicFilters, selectedParameter)}&gt;                     &lt;option key={-1} value={-1}&gt;All&lt;\/option&gt;                     {                         values.map(function (val, idx) {                                 return &lt;option key={idx} value={val[optionIndex]}&gt;{val[optionValue]}&lt;\/option&gt;                             })                         }                 &lt;\/select&gt;             &lt;\/div&gt;:&lt;div&gt;No data&lt;\/div&gt;         };          return (this.state.genres !== undefined && this.state.genres !== null)?         &lt;div&gt;             &lt;div&gt;                 &lt;div&gt;                     &lt;div className=&quot;genres&quot; id=&quot;genres&quot;&gt;                         &lt;div style={{&quot;font-weight&quot;:&quot;bold&quot;}}&gt;Genres:&lt;\/div&gt;                         {                             this.state.genres.map(function (val, idx) {                                 return &lt;div key={idx}&gt;                                     &lt;input checked={genresContains(val[&quot;GenreID&quot;])} type=&quot;checkbox&quot;  value={val[&quot;GenreID&quot;]||null} onChange={onGenreChanged.bind(musicFilters)}\/&gt;                                     &lt;span className=&quot;js-genres&quot;&gt;{val[&quot;Genre&quot;]}&lt;\/span&gt;                                 &lt;\/div&gt;                                 })                             }                     &lt;\/div&gt;                     &lt;div className=&quot;selects&quot;&gt;                         {                             renderDropDown(&quot;Performers&quot;, &quot;performers&quot;, this.state.performers, musicFilters.state.selected.performerID,  &quot;PerformerID&quot;, &quot;Performer&quot;,  &quot;performerID&quot; )                             }                         {                             renderDropDown(&quot;Composers&quot;, &quot;composers&quot;, this.state.composers, musicFilters.state.selected.composerID, &quot;ComposerID&quot;, &quot;Composer&quot;,  &quot;composerID&quot; )                             }                         {                             renderDropDown(&quot;Albums&quot;, &quot;albums&quot;, this.state.albums, musicFilters.state.selected.albumID, &quot;AlbumID&quot;, &quot;Album&quot;,  &quot;albumID&quot; )                             }                         {                             renderDropDown(&quot;Casts&quot;, &quot;casts&quot;, this.state.casts, musicFilters.state.selected.castID, &quot;CastID&quot;, &quot;Cast&quot;, &quot;castID&quot;, {clear:&quot;both&quot;})                             }                     &lt;\/div&gt;                 &lt;\/div&gt;                  &lt;div className=&quot;musicContainer&quot;&gt;                     &lt;div className=&quot;musics&quot;&gt;                         &lt;label&gt;Musics:&lt;\/label&gt;&lt;br\/&gt;                         &lt;div style={{&quot;overflow-y&quot;: &quot;scroll&quot;, &quot;height&quot;: &quot;500px&quot;}}&gt;                                 &lt;table&gt;                                     &lt;tbody&gt;                                     {                                         this.state.musics.map(function (val, idx) {                                                 return &lt;tr&gt;&lt;td&gt;{val[&quot;Music&quot;]}&lt;\/td&gt;&lt;\/tr&gt;;                                             })                                     }                                     &lt;\/tbody&gt;                                 &lt;\/table&gt;                         &lt;\/div&gt;                     &lt;\/div&gt;                 &lt;\/div&gt;             &lt;\/div&gt;         &lt;\/div&gt;:         &lt;div&gt;No data&lt;\/div&gt;;     },  \/\/ end of lifetime methods \/\/\/\/\/\/     raiseEvent: function(eventHandler, eventArgs) {         if (eventHandler) {             if (typeof(eventHandler) === 'string') {                 eval(eventHandler(this, eventArgs));             }             else {                 eventHandler(this, eventArgs);             }         }     },      onFilterChanged: function(selectedParameter, e) {         var selected = _.clone(this.state.selected);         selected[selectedParameter] = parseInt($(e.currentTarget).val()) || null;         this.setState(             {selected: selected}             , this.raiseEvent.bind(this, eval(this.props.onFilterChanged), selected)         );     },      onGenreChanged: function() {         var genresFound = [];         $(&quot;#genres&quot;).find(&quot;input:checked&quot;).map(function() {             genresFound.push(parseInt($(this).val()));         });         var stateCopy = music.deepCopy(this.state);         stateCopy.genresFound = genresFound;         this.setState(stateCopy);         music.reLoadDetailsAndFilters(             {genreIDs: genresFound,                 performerID: this.state.selected.performerID,                 albumID: this.state.selected.albumID,                 composerID: this.state.selected.composerID,                 castID: this.state.selected.castID});     },      areNullablesEqual: function(first, second) {         return first === second || (first === null && second === null);     }  }); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, React \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u0435\u0435. \u0413\u043b\u0430\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0438\u0437-\u0437\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 render. \u042d\u0442\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e React \u0432\u043e\u0437\u043b\u0430\u0433\u0430\u0435\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430.<\/p>\n<p>  \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u044f \u0441\u043a\u043b\u043e\u043d\u0438\u043b\u0441\u044f \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 Knockout. \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u043b \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0441\u0442\u044c \u2014 \u043c\u0430\u043b\u043e\u0437\u0430\u043c\u0435\u0442\u043d\u044b\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043c\u0435\u0436\u0434\u0443 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u044b \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u0430 \u0438 \u043f\u0443\u0441\u0442\u044b\u0445 \u0434\u0440\u043e\u043f\u0434\u0430\u0443\u043d\u043e\u0432, \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e. \u0422. \u0435. \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0438\u0434\u0438\u0442 \u043d\u0430\u0431\u043e\u0440 \u043f\u0443\u0441\u0442\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/5b1\/de1\/91f\/5b1de191fc0447d9b99413be3d574338.png\"\/><\/p>\n<p>  \u0418 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u0443\u0441\u0442\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u044b \u0434\u0430\u043d\u043d\u044b\u043c\u0438:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/bcb\/c90\/24e\/bcbc9024ea8a4163b1a6f4cc1ceb604f.png\"\/><\/p>\n<p>  \u041e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0430 300. <\/p>\n<p>  \u042f \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0434\u043e 15 000 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u0442\u0430\u043b\u0430 \u043e\u0442\u0447\u0435\u0442\u043b\u0438\u0432\u043e\u0439:  <\/p>\n<div class=\"oembed\">\n<div>\n<div style=\"left: 0px; width: 100%; height: 0px; position: relative; padding-bottom: 56.2493%;\"><iframe src=\"https:\/\/www.youtube.com\/embed\/lmTc5wWLmVY?rel=0&amp;showinfo=1\" frameborder=\"0\" allowfullscreen=\"true\" webkitallowfullscreen=\"true\" mozallowfullscreen=\"true\" style=\"top: 0px; left: 0px; width: 100%; height: 100%; position: absolute;\"><\/iframe><\/div>\n<\/div>\n<\/div>\n<p>  \u041d\u0430 \u0442\u043e\u0439 \u0436\u0435 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 (15 000 \u0437\u0430\u043f\u0438\u0441\u0435\u0439) \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c \u0432\u0435\u0434\u0435\u0442 \u0441\u0435\u0431\u044f \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e:  <\/p>\n<div class=\"oembed\">\n<div>\n<div style=\"left: 0px; width: 100%; height: 0px; position: relative; padding-bottom: 56.2493%;\"><iframe src=\"https:\/\/www.youtube.com\/embed\/t193vhkuLqg?rel=0&amp;showinfo=1\" frameborder=\"0\" allowfullscreen=\"true\" webkitallowfullscreen=\"true\" mozallowfullscreen=\"true\" style=\"top: 0px; left: 0px; width: 100%; height: 100%; position: absolute;\"><\/iframe><\/div>\n<\/div>\n<\/div>\n<p>  \u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0434\u043b\u044f Knockout:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/5d3\/f4c\/606\/5d3f4c6063cf4ac3bce28ba70506070c.png\"\/><br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/a02\/703\/a59\/a02703a59c2a40d2bde5dcb40a6b7458.png\"\/><br \/>  \u0412\u0440\u0435\u043c\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u043e 3.87 \u0441.<\/p>\n<p>  \u0410 \u0432\u043e\u0442 React \u0441 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/1dd\/14c\/017\/1dd14c017bac4dafaab4d3b1c829e25a.png\"\/><br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/166\/5e1\/895\/1665e18950494ff79851208731b76ef4.png\"\/><br \/>  \u0412\u0440\u0435\u043c\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u2014 2.36 \u0441.<\/p>\n<p>  \u0418, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, React c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/54c\/444\/d31\/54c444d314734e8081de53da58210982.png\"\/><br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/968\/83c\/be8\/96883cbe8f4444079a759d38c9f61986.png\"\/><br \/>  \u0412\u0440\u0435\u043c\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u2014 5.95 \u0441.<\/p>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u043b\u0438\u043d\u043d\u0443\u044e \u0441\u0438\u043d\u044e\u044e \u043f\u043e\u043b\u043e\u0441\u043a\u0443 \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c \u2014 \u044d\u0442\u0430 \u043b\u0438\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 3 \u0441\u0435\u043a\u0443\u043d\u0434 \u2014 \u0432\u0440\u0435\u043c\u044f, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.<\/p>\n<h2>\u0412\u044b\u0432\u043e\u0434\u044b:<\/h2>\n<p>  <b>1.<\/b> \u0421\u0430\u043c\u044b\u043c \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0438\u0437 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f React \u0441 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435. \u0412\u0440\u0435\u043c\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441 15 000 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043d\u0435 \u043f\u0440\u0435\u0432\u044b\u0441\u0438\u043b\u043e 3 \u0441\u0435\u043a\u0443\u043d\u0434. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 Knockout \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e \u043e\u043a\u043e\u043b\u043e 4 \u0441\u0435\u043a\u0443\u043d\u0434. \u0421 \u0443\u0447\u0435\u0442\u043e\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e 40% \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0443\u0445\u043e\u0434\u044f\u0442 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 3 \u0441\u0435\u043a\u0443\u043d\u0434, React \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0431\u0435\u0437\u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u043c. <br \/>  <b>2.<\/b> \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043d\u0430 Knockout \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u043c\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430\u043c\u0438 \u0432 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043e\u0431\u044a\u0435\u043c\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445.<br \/>  <b>3.<\/b> \u0412 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043d\u0430 React \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e \u0434\u043e\u043b\u0433\u0438\u043c \u0441\u043a\u0440\u044b\u0442\u044b\u043c \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.<\/p>\n<h2>\u041e\u0431\u0449\u0438\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438:<\/h2>\n<p>  <b>1.<\/b> \u0415\u0441\u043b\u0438 \u043e\u0431\u044a\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043d\u0435\u0432\u0435\u043b\u0438\u043a, \u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0432 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u044b \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0439\u0442\u0435 Knockout. \u0412\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u044b\u0439, \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u043a\u043e\u0434.<br \/>  <b>2.<\/b> \u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u0435\u0441\u043b\u0438 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0439\u0442\u0435 React c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u043e\u043c \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435.<br \/> \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:\/\/habrahabr.ru\/post\/314746\/\"> https:\/\/habrahabr.ru\/post\/314746\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/dff\/21e\/94b\/dff21e94bebc401abf3d185722678da4.png\"\/><br \/>  <i>\u0410\u0432\u0442\u043e\u0440: \u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u041a\u043b\u0438\u043c\u0435\u043d\u043a\u043e, Senior Developer, DataArt<\/i><\/p>\n<p>  \u041e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0430\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043b\u0438\u0448\u044c JavaScript \u0438 jQuery \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u043d\u043e\u0433\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u2014 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043b\u043e\u0445\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u0441\u043f\u0430\u0433\u0435\u0442\u0442\u0438-\u043a\u043e\u0434, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u0441\u043a\u0440\u044b\u0442\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0438 \u0441 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438, \u043a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435, \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0435\u0444\u0435\u043a\u0442\u043e\u0432.<\/p>\n<p>  \u0414\u043b\u044f \u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043f\u0440\u0438\u0447\u0435\u043c \u043f\u043e\u0434\u0447\u0430\u0441 \u0442\u0440\u0443\u0434\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0438\u0437 \u043d\u0438\u0445 \u043b\u0443\u0447\u0448\u0435. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0434\u0432\u0443\u0445 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432: Knockout, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0435\u0433\u043e MVVM-\u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u0438 React, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u043e\u0442 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442. <\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0449\u0443\u044e \u043c\u0443\u0437\u044b\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f, \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0436\u0430\u043d\u0440\u0430\u043c, \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0430\u043c, \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f\u043c, \u0441\u0431\u043e\u0440\u043d\u0438\u043a\u0430\u043c \u0438 \u0440\u0430\u0434\u0438\u043e\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c.<\/p>\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-280642","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/280642","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=280642"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/280642\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=280642"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=280642"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=280642"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}