{"id":279496,"date":"2016-05-03T17:35:02","date_gmt":"2016-05-03T13:35:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=279496"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=279496","title":{"rendered":"\u041a\u0430\u043a \u043c\u044b \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0438 \u0431\u043e\u044f\u0442\u044c\u0441\u044f \u0442\u0438\u043a\u0435\u0442\u043e\u0432 \u043d\u0430 UI"},"content":{"rendered":"<p>       \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.<br \/>  \u041f\u0440\u043e\u0448\u043b\u043e \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0433\u043e\u0434\u0430 \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u0430\u043a \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c ReactJS \u0432 \u043d\u0430\u0448\u0435\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u0438 \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0441\u043e\u0437\u0440\u0435\u043b\u0438 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u043c, \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u0435\u0435 \u0441\u0442\u0430\u043b\u0430 \u043d\u0430\u0448\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0441\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0432\u0435\u043b\u0438 \u043d\u0430\u0441 \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0435\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c.<br \/>  \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438. \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0438 \u044f \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u043a\u0430\u043a \u0435\u0441\u0442\u044c. \u0412\u0441\u0435 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u044b \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0438 \u044f \u0437\u0430\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044e \u0432 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043a \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0443\u0434\u043e\u0431\u043d\u0435\u0435<\/p>\n<h2>\u0410 \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430\u0447\u0435\u043c \u0432\u0441\u0451 \u044d\u0442\u043e<\/h2>\n<p>  \u041c\u044b \u2014 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f, \u043d\u0430\u0448 \u0448\u0442\u0430\u0442 \u2014 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 50 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, 20 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438. \u0421\u0435\u0439\u0447\u0430\u0441 \u0443 \u043d\u0430\u0441 4 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043f\u043e 5 fullstack \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u041d\u043e \u043e\u0434\u043d\u043e \u0434\u0435\u043b\u043e \u2014 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0435\u0431\u044f fullstack-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c, \u0430 \u0434\u0440\u0443\u0433\u043e\u0435 \u0434\u0435\u043b\u043e \u2014 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e <u>\u0445\u043e\u0440\u043e\u0448\u043e<\/u> \u0432 \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u044f\u0445 \u0440\u0430\u0431\u043e\u0442\u044b SQL Server&#8217;\u0430, ASP.NET, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 C#, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0432 OOP, DDD, \u0437\u043d\u0430\u0442\u044c HTML, CSS, JS \u0438 \u0443\u043c\u0435\u0442\u044c \u044d\u0442\u0438\u043c \u0432\u0441\u0435\u043c \u0440\u0430\u0437\u0443\u043c\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0442\u044f\u0433\u043e\u0442\u0435\u0435\u0442 \u043a \u0447\u0435\u043c\u0443-\u0442\u043e \u0441\u0432\u043e\u0435\u043c\u0443, \u043d\u043e \u0432\u0441\u0435 \u043c\u044b \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 .NET \u0438 90% \u043a\u043e\u0434\u0430 \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u043d\u0430 C#.<br \/>  \u041d\u0430\u0448 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u2014 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u0430 \u2014 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0438 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0439 \u0441\u0430\u043c\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u043f\u043e\u0434 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0430\u0439\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u044b \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438, \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u042d\u0442\u043e\u0442 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0430\u0439\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e UI&#8217;\u0430, \u0438 \u0447\u0435\u043c \u0441\u0438\u043b\u044c\u043d\u0435\u0435 \u043c\u044b \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0435\u043c\u0441\u044f, \u0447\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u043d\u043a\u0438\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043c\u044b \u0434\u0430\u0451\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c, \u0447\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0444\u0438\u0447 \u043c\u044b \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c \u043e\u043d \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u044b\u0442\u044c \u0433\u043e\u043b\u043e\u0441\u043b\u043e\u0432\u043d\u044b\u043c, \u043f\u0430\u0440\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u043e\u0432 (\u0443\u0436\u0435 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c, \u0438 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u043e\u0432 \u0442\u0430\u043c \u043e\u0442\u043d\u044e\u0434\u044c \u043d\u0435 \u043f\u0430\u0440\u0430!):<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/d61\/99f\/b9a\/d6199fb9a9ec417e97406841057fe6f6.png\"\/>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0424\u0438\u043b\u044c\u0442\u0440 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/868\/2e9\/1d0\/8682e91d0938408ca825b5a6efc72d46.png\"\/>  <\/div>\n<\/div>\n<p>  \u041a\u0430\u043a \u0436\u0435 \u043c\u044b \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u0441 \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430 UI&#8217;\u0435\u043c \u0440\u0430\u043d\u044c\u0448\u0435? \u0421\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c \u043c\u044b \u043e\u0442\u043a\u0440\u043e\u0432\u0435\u043d\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f \u043f\u043b\u043e\u0445\u043e. \u0412 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043e\u0442\u0434\u0435\u043b\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043a\u0443\u0441\u043a\u043e\u0432 HTML&#8217;\u0430 javascript&#8217;\u043e\u043c. \u041b\u0438\u0431\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f JQuery. \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0442\u0430\u043a\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u044d\u0442\u043e \u0432\u044b\u043b\u0438\u0432\u0430\u043b\u043e\u0441\u044c \u0432 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u043a\u0438, \u043f\u0440\u0435\u043b\u043e\u0430\u0434\u0435\u0440\u044b \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0438\u0445 \u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0435 \u0431\u0430\u0433\u0438. \u0421 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044d\u0442\u043e \u0431\u044b\u043b\u0438 \u0441\u0430\u043c\u044b\u0435 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u043c\u0430\u043a\u0430\u0440\u043e\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0441\u0435 \u0431\u043e\u044f\u043b\u0438\u0441\u044c. \u041b\u044e\u0431\u043e\u0439 \u0442\u0438\u043a\u0435\u0442 \u043d\u0430 UI \u043d\u0430 \u043e\u0446\u0435\u043d\u043a\u0435 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u043b \u043e\u0446\u0435\u043d\u043a\u0443 L \u0438 \u0432\u044b\u043b\u0438\u0432\u0430\u043b\u0441\u044f \u0432 \u0442\u043e\u043d\u043d\u0443 \u0431\u0430\u0442\u0445\u0451\u0440\u0442\u0430. \u0418 \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f \u0431\u044b\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u0431\u0430\u0433\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u0442\u0430\u043a\u0438\u043c UI&#8217;\u0435\u043c. \u041f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u043e \u044d\u0442\u043e \u0442\u0430\u043a: \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u043b\u0430\u0441\u044c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043c\u0435\u043b\u043a\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430, \u0437\u0430\u0432\u043e\u0434\u0438\u043b\u0441\u044f \u0442\u0438\u043a\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e\u0431\u044b \u0435\u0451 \u043f\u043e\u0447\u0438\u043d\u0438\u0442\u044c, \u043e\u043d\u0430 \u0447\u0438\u043d\u0438\u043b\u0430\u0441\u044c, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435\u043c\u0438\u043d\u0443\u0435\u043c\u043e \u0440\u0430\u0437\u0432\u0430\u043b\u0438\u0432\u0430\u043b\u043e\u0441\u044c \u0447\u0442\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 \u044d\u0442\u043e \u0447\u0443\u0434\u043e \u043d\u0435 \u0431\u044b\u043b\u043e. \u041e\u043f\u044f\u0442\u044c-\u0442\u0430\u043a\u0438, \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u0431\u044b\u0442\u044c \u0433\u043e\u043b\u043e\u0441\u043b\u043e\u0432\u043d\u044b\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 \u0436\u0438\u0437\u043d\u0438.<br \/>  \u041f\u0435\u0440\u0435\u0434 \u0432\u0430\u043c\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041d\u0435 \u0432\u0434\u0430\u0432\u0430\u044f\u0441\u044c \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u0431\u0438\u0437\u043d\u0435\u0441\u0443 \u0441\u043a\u0430\u0436\u0443 \u0442\u043e\u043b\u044c\u043a\u043e, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0443 \u043d\u0430\u0441 \u2014 \u044d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 REST-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0440\u044f\u0434\u0447\u0438\u043a\u0438 \u043d\u0430\u0448\u0438\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u044f\u0432\u043b\u044f\u0435\u043c\u0441\u044f backend&#8217;\u043e\u043c \u0438\u0445 \u0441\u0430\u0439\u0442\u0430). \u0423 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0435\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u044d\u0442\u0430\u043f\u0430\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435\u0439, \u0438 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c, \u0431\u044b\u043b \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/7bf\/fb6\/2b0\/7bffb62b07ad46a492dcf8c0c19cbfb3.png\"\/>  <\/div>\n<\/div>\n<p>  \u0410 \u0432\u043e\u0442 \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0430:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u043a\u043e\u043d\u0442\u043e\u043b\u043b\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\u041a\u0443\u0441\u043e\u0447\u0435\u043a \u0432\u044c\u044e\u0445\u0438  <\/p>\n<pre><code class=\"html\">&lt;h2 class=&quot;column-header&quot;&gt;         &lt;span class=&quot;link-action&quot;                   data-event-name=&quot;ToggleElements&quot;                   data-event-param='{&quot;selector&quot;:&quot;#WorkFlowAllowance&quot;, &quot;callback&quot;: &quot;toggleWorkflowAvailability&quot;}'&gt;                 \u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u044d\u0442\u0430\u043f\u0430\u0445 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438         &lt;\/span&gt; &lt;\/h2&gt; @Html.HiddenFor(m =&gt; m.IsAllowedForAllWorkflow, new { Id = &quot;IsAllowedForAllWorkflow&quot; }) &lt;div id=&quot;WorkFlowAllowance&quot; class=&quot;@(Model.IsAllowedForAllWorkflow ? &quot;none&quot; : string.Empty) row form_horizontal&quot;&gt;         &lt;table class=&quot;table table_hover table_control @(Model.OperationWorkflowAllowances.Any() ? String.Empty : &quot;none&quot;)&quot; id=&quot;operationAllowanceTable&quot;&gt;                 &lt;thead&gt;                         &lt;tr&gt;                                 &lt;th&gt;\u041c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438&lt;\/th&gt;                                 &lt;th&gt;\u042d\u0442\u0430\u043f&lt;\/th&gt;                         &lt;\/tr&gt;                 &lt;\/thead&gt;                 &lt;tbody&gt;                         @Model.OperationWorkflowAllowances.Each(                         @&lt;tr&gt;                                 &lt;td&gt;                                         @item.Item.WorkflowDisplayName                                         &lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[@(item.Index)].WorkflowName&quot; value=&quot;@item.Item.WorkflowName&quot; \/&gt;                                         &lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[@(item.Index)].WorkflowDisplayName&quot; value=&quot;@item.Item.WorkflowDisplayName&quot; \/&gt;                                         &lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[@(item.Index)].Id&quot; value=&quot;@item.Item.Id&quot; \/&gt;                                 &lt;\/td&gt;                                 &lt;td&gt;                                         &lt;button class=&quot;cell-grid__right button button_icon-only button_red removeOperationAllowance&quot;&gt;&lt;span class=&quot;icon icon_del&quot;&gt;&lt;\/span&gt;&lt;\/button&gt;                                         &lt;span class=&quot;cell-grid__wraps&quot;&gt;@(item.Item.StageName ?? &quot;\u041b\u044e\u0431\u043e\u0439&quot;)&lt;\/span&gt;                                         &lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[@(item.Index)].StageName&quot; value=&quot;@item.Item.StageName&quot; \/&gt;                                         &lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[@(item.Index)].StageDisplayName&quot; value=&quot;@item.Item.StageDisplayName&quot; \/&gt;                                 &lt;\/td&gt;                         &lt;\/tr&gt;)                 &lt;\/tbody&gt;         &lt;\/table&gt;         &lt;div class=&quot;col col_462&quot;&gt;                 &lt;div class=&quot;form-group form-group_all&quot;&gt;                                          &lt;\/div&gt;                 @if (Model.WorkFlows.Any())                 {                         &lt;div&gt;                                 &lt;div class=&quot;form-group&quot;&gt;                                         &lt;label class=&quot;form-label&quot;&gt;&lt;span&gt;\u041c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438&lt;\/span&gt;&lt;\/label&gt;                                         @Html.DropDownList(&quot;WorkflowList&quot;, Model.WorkFlows, new Dictionary&lt;string, object&gt;                                         {                                                 { &quot;class&quot;, &quot;form-control select2 w470&quot; },                                                 { &quot;data-placeholder&quot;, &quot;\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430&quot; },                                                 { &quot;id&quot;, &quot;workflowList&quot; },                                                 { &quot;disabled&quot;, &quot;disabled&quot; }                                         })                                 &lt;\/div&gt;                                 &lt;div class=&quot;form-group&quot;&gt;                                         &lt;div class=&quot;form-list&quot;&gt;                                                 &lt;input id=&quot;isAllowedForAllStagesForCurrentWorkflow&quot; type=&quot;checkbox&quot; name=&quot;StageMechanicsRegistratioName&quot; autocomplete=&quot;off&quot;&gt;                                                 &lt;label for=&quot;isAllowedForAllStagesForCurrentWorkflow&quot;&gt;\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 &lt;span id=&quot;exceptAnonymus&quot;&gt;&lt;\/span&gt;&lt;span id=&quot;workflowName&quot;&gt;&lt;\/span&gt;&lt;\/label&gt;                                         &lt;\/div&gt;                                 &lt;\/div&gt;                                 &lt;div class=&quot;form-group&quot;&gt;                                         &lt;label class=&quot;form-label&quot;&gt;&lt;span&gt;\u042d\u0442\u0430\u043f&lt;\/span&gt;&lt;\/label&gt;                                         @Html.DropDownList(&quot;WorkflowStageList&quot;, new SelectListItem[0], new Dictionary&lt;string, object&gt;                                         {                                                 { &quot;class&quot;, &quot;form-control select2 w470&quot; },                                                 { &quot;data-placeholder&quot;, &quot;\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430&quot; },                                                 { &quot;id&quot;, &quot;workflowStageList&quot; },                                                 { &quot;disabled&quot;, &quot;disabled&quot;}                                         })                                 &lt;\/div&gt;                                 &lt;div class=&quot;form-group&quot;&gt;                                         &lt;button class=&quot;button button_blue&quot; id=&quot;addOperationAllowance&quot;&gt;\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c&lt;\/button&gt;                                 &lt;\/div&gt;                         &lt;\/div&gt;                 }                 else                 {                         @: \u041c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b                 }         &lt;\/div&gt;  &lt;\/div&gt; <\/code><\/pre>\n<p>  \u0410 \u0432\u043e\u0442 js, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u044d\u0442\u0443 \u0432\u044c\u044e\u0445\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c (\u044f \u043d\u0435 \u043f\u0440\u0435\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b \u0446\u0435\u043b\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e, \u043a\u0430\u043a \u0432\u0441\u0451 \u0431\u044b\u043b\u043e \u043f\u0435\u0447\u0430\u043b\u044c\u043d\u043e):  <\/p>\n<pre><code class=\"javascript\">function initOperationAllowance(typeSelector) {         $('#workflowList').prop('disabled', false);         $('#workflowList').trigger('change');          if ($(typeSelector).val() == 'PerformAction') {                 $('#exceptAnonymus').html('(\u043a\u0440\u043e\u043c\u0435 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0445)');         } else {                 $('#exceptAnonymus').html('');         } }  function toggleWorkflowAvailability() {         var element = $(&quot;#IsAllowedForAllWorkflow&quot;);         $('#operationAllowanceTable tbody tr').remove();         parameters.selectedAllowances = [];         return  element.val().toLowerCase() == 'true' ? element.val(false) : element.val(true); }  function deleteRow(row) {         var index = getRowIndex(row);         row.remove();         parameters.selectedAllowances.splice(index, 1);          $('#operationAllowanceTable input').each(function () {                 var currentIndex = getFieldIndex($(this));                 if (currentIndex &gt; index) {                         decrementIndex($(this), currentIndex);                 }         });          if (parameters.selectedAllowances.length == 0) {                 $('#operationAllowanceTable').hide();         } }  function updateWorkflowSteps(operationType) {         var workflow = $('#workflowList').val();         if (workflow == '') {                 $('#isAllowedForAllStagesForCurrentWorkflow')                         .prop('checked', false)                         .prop('disabled', 'disabled');                 refreshOptionList(                         $('#workflowStageList'),                         [{ Text: '\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430', Value: '', Selected: true }]                 );                 $('#workflowStageList').trigger('change').select2('enable', false);                 return;         }          var url = parameters.stagesUrlTemplate + '?workflowName=' + workflow + '&OperationTypeName=' + operationType;                  $.getJSON(url, null, function (data) {                  $('#isAllowedForAllStagesForCurrentWorkflow')                         .prop('checked', false)                         .removeProp('disabled');                  refreshOptionList($('#workflowStageList'), data);                 $('#workflowStageList').trigger('change').select2('enable', true);         }); }  function refreshOptionList(list, data) {         list.find('option').remove();          $.each(data, function (index, itemData) {                  var option = new Option(itemData.Text, itemData.Value, null, itemData.Selected);                  list[0].add(option);         }); }  function AddRow(data) {          var rowsCount = $('#operationAllowanceTable tr').length;         var index = rowsCount - 1;          var result =                 '&lt;tr ' + (rowsCount % 2 != 0 ? 'class=&quot;bgGray&quot;&gt;' : '&gt;') +                         '&lt;td&gt;' +                                 '{DisplayWorkflowName}' +                                 '&lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[' + index + '].WorkflowName&quot; value=&quot;{WorkflowName}&quot;\/&gt;' +                                 '&lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[' + index + '].Id&quot; value=&quot;&quot;\/&gt;' +                                 '&lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[' + index + '].WorkflowDisplayName&quot; value=&quot;{DisplayWorkflowName}&quot;\/&gt;' +                         '&lt;\/td&gt;' +                         '&lt;td&gt;' +                                 '&lt;button class=&quot;cell-grid__right button button_icon-small button_red removeOperationAllowance&quot;&gt;&lt;span class=&quot;icon icon_del&quot;&gt;&lt;\/span&gt;&lt;\/button&gt;' +                                 '&lt;span class=&quot;cell-grid__wraps&quot;&gt;{DisplayStageName}&lt;\/span&gt;' +                                 '&lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[' + index + '].StageName&quot; value=&quot;{StageName}&quot;\/&gt;' +                                 '&lt;input type=&quot;hidden&quot; name=&quot;OperationTypeViewModel.OperationWorkflowAllowances[' + index + '].StageDisplayName&quot; value=&quot;{DisplayStageName}&quot;\/&gt;' +                 '&lt;\/td&gt;' +                 '&lt;\/tr&gt;';          for (key in data) {                 result = result.replace(new RegExp('{' + key + '}', 'g'), data[key]);         }          $('#operationAllowanceTable').show().append(result); }  function IsValidForm() {         var result = ValidateList($('#workflowList'), '\u0412\u044b \u043d\u0435 \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438') &                 ValidateListWithCheckBox($('#workflowStageList'), $('#isAllowedForAllStagesForCurrentWorkflow'), '\u0412\u044b \u043d\u0435 \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u044d\u0442\u0430\u043f \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438');          if (!result)                 return false;          var workflowName = $('#workflowList').val();         var stageName = '';          if (!$('#isAllowedForAllStagesForCurrentWorkflow').is(':checked'))         {                 stageName = $('#workflowStageList').val();         }          hideError($('#workflowList'));         hideError($('#workflowStageList'));          for (var i = 0; i &lt; parameters.selectedAllowances.length; i++)         {                 if (parameters.selectedAllowances[i].workflow == workflowName &&                         parameters.selectedAllowances[i].stage == stageName)                 {                         if (stageName == '')                         {                                 showError($('#workflowList'), '\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u044d\u0442\u043e\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0443\u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430');                         }                         else                         {                                 showError($('#workflowStageList'), '\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0443\u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430');                         }                         result = false;                 }                 else if (parameters.selectedAllowances[i].workflow == workflowName &&                         parameters.selectedAllowances[i].stage == '') {                         showError($('#workflowList'), '\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u044d\u0442\u043e\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0443\u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430');                         result = false;                 }         }          return result; }  function ValidateList(field, message) {         if (field.val() == &quot;&quot;) {                 showError(field, message);                 return false;         }          hideError(field);          return true; }  function ValidateListWithCheckBox(field, checkBoxField, message) {         if (!checkBoxField.prop('checked')) {                 return ValidateList(field, message);         }          hideError(field);         return true; }  function showError(field, message) {         if (typeof (message) === 'undefined') {                 message = '\u041f\u043e\u043b\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f';         }          field.addClass('input-validation-error form-control_error');         field.parent('.form-group').find('div.tooltip-error').remove();         field.closest('.form-group').append(                 '&lt;div class=&quot;tooltip-icon tooltip-icon_error&quot;&gt;&lt;div class=&quot;tooltip-icon__content&quot;&gt;' +                 '&lt;strong&gt;\u041e\u0448\u0438\u0431\u043a\u0430&lt;\/strong&gt;&lt;br&gt;' + message + '&lt;\/div&gt;&lt;\/div&gt;'); }  function hideError(field) {         field.removeClass('input-validation-error form-control_error');         field.parent('.form-group').find('div.tooltip-icon_error').remove(); }  function getRowIndex(row) {         return getFieldIndex(row.find('input:first')); }  function getFieldIndex(field) {         var name = field.prop('name');          var startIndex = name.indexOf('[') + 1;         var endIndex = name.indexOf(']');          return name.substr(startIndex, endIndex - startIndex); }  function decrementIndex(field, index) {         var name = field.prop('name');         var newIndex = index - 1;         field.prop('name', name.replace('[' + index + ']', '[' + newIndex + ']')); }  function InitializeWorkflowAllowance(settings) { \t$(function() { \t\t\tparameters.selectedAllowances = settings.selectedAllowances;  \t\t\tinitOperationAllowance(parameters.typeSelector);  \t\t\t$('#workflowList').change(function () { \t\t\t\t\tupdateWorkflowSteps($(parameters.typeSelector).val()); \t\t\t});  \t\t\t$('#addOperationAllowance').click(function (event) { \t\t\t\t\tevent.preventDefault();  \t\t\t\t\tif (IsValidForm()) { \t\t\t\t\t\t\tvar data = { \t\t\t\t\t\t\t\t\t'StageName': $('#workflowStageList').val(), \t\t\t\t\t\t\t\t\t'WorkflowName': $('#workflowList').val(), \t\t\t\t\t\t\t};  \t\t\t\t\t\t\tif ($('#isAllowedForAllStagesForCurrentWorkflow').is(':checked')) { \t\t\t\t\t\t\t\t\tdata.DisplayWorkflowName = $('#workflowList option[value=' + data.WorkflowName + ']').text(); \t\t\t\t\t\t\t\t\tdata.DisplayStageName = '\u041b\u044e\u0431\u043e\u0439'; \t\t\t\t\t\t\t\t\tdata.StageName = ''; \t\t\t\t\t\t\t} \t\t\t\t\t\t\telse { \t\t\t\t\t\t\t\t\tdata.DisplayWorkflowName = $('#workflowList option[value=' + data.WorkflowName + ']').text(); \t\t\t\t\t\t\t\t\tdata.DisplayStageName = $('#workflowStageList option[value=' + data.StageName + ']').text(); \t\t\t\t\t\t\t}  \t\t\t\t\t\t\tAddRow(data);  \t\t\t\t\t\t\tif (data.StageName == '') { \t\t\t\t\t\t\t\t\tvar indexes = [];  \t\t\t\t\t\t\t\t\t\/\/ \u041d\u0443\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u044d\u0442\u0430\u043f\u044b \t\t\t\t\t\t\t\t\tfor (var i = 0; i &lt; parameters.selectedAllowances.length; i++) { \t\t\t\t\t\t\t\t\t\t\tif (parameters.selectedAllowances[i].workflow == data.WorkflowName) { \t\t\t\t\t\t\t\t\t\t\t\t\tindexes.push(i); \t\t\t\t\t\t\t\t\t\t\t} \t\t\t\t\t\t\t\t\t}  \t\t\t\t\t\t\t\t\t$(&quot;#operationAllowanceTable tbody tr&quot;).filter(function (index) { \t\t\t\t\t\t\t\t\t\t\treturn $.inArray(index, indexes) &gt; -1; \t\t\t\t\t\t\t\t\t}).each(function () { \t\t\t\t\t\t\t\t\t\t\tdeleteRow($(this)); \t\t\t\t\t\t\t\t\t}); \t\t\t\t\t\t\t}  \t\t\t\t\t\t\tparameters.selectedAllowances.push({ \t\t\t\t\t\t\t\t\tworkflow: data.WorkflowName, \t\t\t\t\t\t\t\t\tstage: data.StageName \t\t\t\t\t\t\t});  \t\t\t\t\t\t\t$(&quot;#workflowList&quot;).val('').trigger('change'); \t\t\t\t\t\t\tupdateWorkflowSteps($(parameters.typeSelector).val()); \t\t\t\t\t} \t\t\t});  \t\t\t$('#isAllowedForAllStagesForCurrentWorkflow').click(function () { \t\t\t\t\tif ($(this).is(&quot;:checked&quot;)) { \t\t\t\t\t\t\t$('#workflowStageList').prop('disabled', 'disabled'); \t\t\t\t\t} \t\t\t\t\telse { \t\t\t\t\t\t\t$('#workflowStageList').removeProp('disabled'); \t\t\t\t\t} \t\t\t});  \t\t\t$('#operationAllowanceTable').on('click', 'button.removeOperationAllowance', function (event) { \t\t\t\t\tvar row = $(this).parent().parent(); \t\t\t\t\tsetTimeout(function () { \t\t\t\t\t\t\tdeleteRow(row); \t\t\t\t\t}, 20); \t\t\t\t\tevent.preventDefault(); \t\t\t}); \t}); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435, \u0432\u0441\u0451 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0447\u0430\u043b\u044c\u043d\u043e.<\/p>\n<h2>\u041d\u043e\u0432\u0430\u044f \u043d\u0430\u0434\u0435\u0436\u0434\u0430<\/h2>\n<p>  \u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0442\u0430\u043a \u0436\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u043b\u044c\u0437\u044f. \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u0431\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u043c\u044b \u043f\u0440\u0438\u0448\u043b\u0438 \u043a \u0432\u044b\u0432\u043e\u0434\u0443, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432\u043e \u0444\u0440\u043e\u043d\u0442-\u044d\u043d\u0434 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0442 \u043d\u0430\u0441 \u043d\u0430 \u0438\u0441\u0442\u0438\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c. \u041c\u044b \u043d\u0430\u043d\u044f\u043b\u0438 \u0441\u0443\u0434\u044f \u043f\u043e \u043e\u0442\u0437\u044b\u0432\u0430\u043c \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e \u0444\u0440\u0438\u043b\u0430\u043d\u0441\u0435\u0440\u0430-\u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0449\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b \u043d\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c React. \u041e\u043d \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0443 \u043d\u0430\u0441, \u043d\u043e \u0443\u0441\u043f\u0435\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0430\u0440\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043a \u0447\u0435\u043c\u0443, \u0438 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u044f \u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u0434\u0432\u043e\u044f\u043a\u0438\u043c\u0438. \u041c\u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f React \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f <a href=\"https:\/\/facebook.github.io\/react\/docs\/tutorial.html\">\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0430 \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435<\/a>, \u043d\u043e \u043e\u043d \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u043d\u0435 \u0432\u0441\u0435\u043c. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u0445\u0430\u0440\u0434\u043a\u043e\u0440\u043d\u044b\u0435 \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0449\u0438\u043a\u0438 \u043b\u044e\u0431\u044f\u0442 javascript, \u043d\u043e \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043c\u0438\u0440\u0435 \u043d\u0430\u0448\u0435\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 javascript \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c\u044e \u043d\u0435 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f (\u044d\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044f\u0433\u043a\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u044d\u0442\u0438 webpack&#8217;\u0438 \u0438 grunt&#8217;\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0443\u0433\u0430\u043b\u0438 \u043d\u0430\u0441. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u043e\u0432 \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e UI&#8217;\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0440\u0430\u0437\u043d\u044b\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c, \u0441 \u043a\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0434\u0435\u043b\u043e. \u0421\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u043b\u0438, \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u043a\u043e\u0434. \u041c\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043b\u0438 Angular, React \u0438 Knockout. \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043d\u0435 \u043f\u0440\u043e\u0448\u0451\u043b \u0434\u0430\u0436\u0435 \u0441\u0442\u0430\u0434\u0438\u044e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430, \u0438 \u044f \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u043e\u043c\u043d\u044e \u0443\u0436\u0435, \u043f\u043e \u043a\u0430\u043a\u043e\u0439 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a\u0430\u043c\u0438 Angular&#8217;\u0430 \u0438 React&#8217;\u0430 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u043b\u0430\u0441\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0430\u044f \u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0441\u043a\u0430\u044f \u0432\u043e\u0439\u043d\u0430! <br \/>  \u0428\u0443\u0442\u043a\u0430 \ud83d\ude42 \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0431\u044b\u043b\u043e \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a\u0443, \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u043d\u0438 \u0442\u043e\u0442, \u043d\u0438 \u0434\u0440\u0443\u0433\u043e\u0439. \u0412\u0441\u0435 \u043c\u044f\u043b\u0438\u0441\u044c \u0438 \u043d\u0435 \u043c\u043e\u0433\u043b\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u0440\u0435\u0448\u0438\u0442\u044c. \u0412 Angular&#8217;\u0435 \u0432\u0441\u0435\u0445 \u0440\u0430\u0437\u0434\u0440\u0430\u0436\u0430\u043b\u0430 \u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c, \u0430 \u0432 React&#8217;\u0435 \u2014 \u0441\u0442\u0440\u0451\u043c\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432 Visual Studio \u043d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0431\u044b\u043b\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u043c \u0444\u0430\u043a\u0442\u043e\u043c. <br \/>  \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e \u0434\u043b\u044f \u043d\u0430\u0441, \u043d\u0430\u043c \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0448\u0451\u043b \u043d\u0430\u0448 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0438\u043a (\u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u0443\u0435\u0442, \u043d\u043e \u0434\u0435\u0440\u0436\u0438\u0442 \u0440\u0443\u043a\u0443 \u043d\u0430 \u043f\u0443\u043b\u044c\u0441\u0435. \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0441\u0442\u0430\u043b\u043e \u044f\u0441\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u044b \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0430 \u043d\u0435 \u0434\u0430\u043b\u0438, \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0442\u0440\u0430\u0442\u0438\u0442 \u0432\u0440\u0435\u043c\u044f \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e \u043d\u0430 \u0447\u0442\u043e (\u0432 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u043d\u0430 \u043c\u043d\u043e\u0433\u043e \u0431<i>\u043e<\/i>\u043b\u044c\u0448\u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f!), \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0435\u043c\u0443. \u0421\u0435\u0439\u0447\u0430\u0441, \u0432\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u044f, \u043f\u043e\u0447\u0435\u043c\u0443 \u0435\u0433\u043e \u0432\u044b\u0431\u043e\u0440 \u0442\u043e\u0433\u0434\u0430 \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u043f\u0430\u043b \u043d\u0430 React, \u0421\u0430\u0448\u0430  <a href=\"https:\/\/habrahabr.ru\/users\/agornik\/\" class=\"user_link\">agornik<\/a> \u0413\u043e\u0440\u043d\u0438\u043a \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u043c\u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 (\u044f \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u0435\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u043d\u0435 \u0434\u043b\u044f \u0445\u043e\u043b\u0438\u0432\u0430\u0440\u0430, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043d\u0435\u043d\u0438\u0435. \u041e\u0440\u0444\u043e\u0433\u0440\u0430\u0444\u0438\u044f, \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430, \u0445\u043e\u0442\u044f \u043a\u043e\u0435-\u0447\u0442\u043e \u044f \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043b):  <\/p>\n<blockquote><p>\u0411\u044b\u043b\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u043e\u0432: \u0440\u0435\u0430\u043a\u0442, \u0430\u043d\u0433\u0443\u043b\u044f\u0440 \u0438 \u0435\u0449\u0435 \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435. \u042f \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b. \u0410\u043d\u0433\u0443\u043b\u044f\u0440 \u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f, \u0440\u0435\u0430\u043a\u0442 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f.<br \/>  \u041d\u043e [\u043a\u043e\u0435-\u043a\u0442\u043e] \u043a\u0440\u0438\u0447\u0430\u043b \u0433\u0440\u043e\u043c\u0447\u0435 \u0432\u0441\u0435\u0445, \u0430 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u043a\u0430\u043a \u043e\u0432\u043e\u0449\u0438. \u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0447\u0438\u0442\u0430\u0442\u044c \u0438 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c.<br \/>  \u042f \u0443\u0432\u0438\u0434\u0435\u043b \u0447\u0442\u043e \u0440\u0435\u0430\u043a\u0442 \u2014 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u043d\u0430 \u043a\u0443\u0447\u0435 \u043a\u0440\u0443\u0442\u044b\u0445 \u0441\u0430\u0439\u0442\u043e\u0432. FB, Yahoo, WhatsApp \u0438 \u0435\u0449\u0435 \u0447\u0442\u043e-\u0442\u043e \u0442\u0430\u043c. \u042f\u0432\u043d\u043e \u0443\u0436\u0435 \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0439 \u0430\u0434\u043e\u043f\u0448\u043d \u0438\u0434\u0435\u0442 \u0438 \u0435\u0441\u0442\u044c \u0431\u0443\u0434\u0443\u0449\u0435\u0435.<br \/>  \u0410 \u043d\u0430 \u0430\u043d\u0433\u0443\u043b\u044f\u0440\u0435 \u2014 [\u043d\u0438\u0447\u0435\u0433\u043e \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e]. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0430 \u0431\u0443\u0434\u0435\u0449\u0435\u0435. \u0423\u0432\u0438\u0434\u0435\u043b \u0447\u0442\u043e \u0432\u0441\u0451 \u0447\u0442\u043e \u043c\u043d\u0435 \u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c \u0432 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0435 \u0430\u043d\u0433\u0443\u043b\u044f\u0440\u0430 \u0445\u043e\u0442\u044f\u0442 \u0432 2.0 \u0443\u0441\u0438\u043b\u0438\u0442\u044c.<br \/>  \u042f \u043f\u043e\u043d\u044f\u043b \u0447\u0442\u043e react \u2014 \u044d\u0442\u043e \u0448\u0442\u0443\u043a\u0430 \u0434\u043b\u044f \u0436\u0438\u0437\u043d\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u0430\u044f \u0440\u0435\u0448\u0430\u044e\u0448\u0430\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443. \u0410 \u0430\u043d\u0433\u0443\u043b\u044f\u0440 \u2014 \u044d\u0442\u043e \u0431\u043e\u0440\u043e\u0434\u0430\u0442\u044b\u0435 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u043a\u0438 \u0438\u0437 \u0433\u0443\u0433\u043b\u0430 \u0438\u0437 \u043c\u043e\u0437\u0433\u0430 \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u044e\u0442 \u0432\u0441\u044f\u043a\u0438\u0435 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438. \u041a\u0430\u043a \u0431\u044b\u043b\u043e \u0441 GWT \u0438\u043b\u0438 \u043a\u0430\u043a \u043e\u043d \u0442\u0430\u043c.<br \/>  \u041d\u0443 \u0438 \u043f\u043e\u043d\u044f\u043b \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0432\u043e\u043b\u0435\u0432\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0432\u0441\u0442\u0430\u0442\u044c \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043e\u0432\u043e\u0449\u0435\u0439, \u0438\u043d\u0430\u0447\u0435 \u043f\u043e\u0431\u0435\u0434\u044f\u0442 \u043a\u0440\u0438\u0447\u0430\u0449\u0438\u0435, \u043d\u043e \u043d\u0435\u043f\u0440\u0430\u0432\u044b\u0435. \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044f \u043d\u0430\u043a\u0438\u0434\u0430\u043b \u0432 \u043a\u0430\u043d\u0430\u043b 33 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u0430 \u043f\u0440\u0443\u0444\u043e\u0432 \u0438 \u0441\u0441\u044b\u043b\u043e\u043a, \u0437\u0430\u0440\u0443\u0447\u0438\u043b\u0441\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 [\u043d\u0430\u0448\u0435\u0433\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440\u0430] \u0438 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0437\u0430\u0431\u0430\u0442\u0445\u0435\u0440\u0442\u0438\u043b.<br \/>  \u0410 \u0435\u0449\u0435 \u044f \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043b \u043a\u0430\u043a\u043e\u0439 \u0431\u044b\u043b \u0430\u0434\u0441\u043a\u0438 \u0432\u0430\u0436\u043d\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442. \u0414\u043b\u044f \u0440\u0435\u0430\u043a\u0442\u0430 \u0431\u044b\u043b \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u043e \u0438 \u0432\u043a\u0440\u044f\u0447\u0438\u0432\u0430\u0442\u044c \u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0430 \u0430\u043d\u0433\u0443\u043b\u044f\u0440 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u0438 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u043b\u0438\u0440\u0443\u0435\u0442 \u0441 [\u0435\u0433\u043e \u043f\u043b\u043e\u0445\u043e\u0439] \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439. <br \/>  \u041f\u043e\u0442\u043e\u043c \u044f \u0435\u0449\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b \u0447\u0442\u043e \u043d\u0430 \u0440\u0435\u0430\u043a\u0442\u0435 \u0432 \u0442\u0435\u043e\u0440\u0438\u0438 \u043c\u043e\u0436\u043d\u043e UI \u0434\u0430\u0436\u0435 \u043d\u0435 \u0434\u043b\u044f \u0432\u0435\u0431\u0430 \u0434\u0435\u043b\u0430\u0442\u044c. \u0418 \u0432\u0441\u044f\u043a\u0438\u0439 \u0442\u0430\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 js \/ react \u0438 \u043a\u0443\u0434\u0430 \u0432\u0441\u0451 \u044d\u0442\u043e \u0438\u0434\u0435\u0442. \u0418 \u043a\u0430\u0440\u043e\u0447\u0435 \u0432\u0430\u0449\u0435 \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0435 \u0431\u0440\u0430\u0442\u044c.<br \/>  \u042f \u043f\u043e\u043d\u044f\u043b \u0447\u0442\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u043b\u044f \u0441\u0442\u0443\u0434\u0438\u0438 \u0432\u043f\u0438\u043b\u044f\u0442 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0432\u0441\u0451 \u0440\u043e\u0432\u043d\u043e \u0442\u0430\u043a \u0438 \u0432\u044b\u0448\u043b\u043e. \u042f \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0430\u0434\u0441\u043a\u0438 \u0434\u043e\u0432\u043e\u043b\u0435\u043d \u044d\u0442\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c)<\/p><\/blockquote>\n<p>  <\/p>\n<h2>\u0427\u0442\u043e \u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c?<\/h2>\n<p>  \u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u043a\u0430\u0440\u0442\u044b \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a \u043c\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0430\u0440\u0438\u043c UI. \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0444\u0440\u043e\u043d\u0442-\u044d\u043d\u0434\u0449\u0438\u043a\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0447\u043d\u0443\u0442 \u0441\u043c\u0435\u044f\u0442\u044c\u0441\u044f, \u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0441 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u2014 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0430\u044f \u043f\u043e\u0431\u0435\u0434\u0430, \u043c\u044b \u0438\u043c \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u044b \ud83d\ude42<br \/>  \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439. \u041a\u0440\u0430\u0442\u043a\u0430\u044f \u0431\u0438\u0437\u043d\u0435\u0441-\u0441\u043f\u0440\u0430\u0432\u043a\u0430: \u0443 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438, \u0417\u0430\u043a\u0430\u0437\u044b, \u041f\u043e\u043a\u0443\u043f\u043a\u0438 \u0438 \u041f\u0440\u043e\u0434\u0443\u043a\u0442\u044b, \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0442\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e <a href=\"https:\/\/en.wikipedia.org\/wiki\/Entity%E2%80%93attribute%E2%80%93value_model\">Entity\u2013attribute\u2013value model<\/a>. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0437\u0430\u0432\u043e\u0434\u0438\u043b\u0438 \u043f\u0440\u044f\u043c\u043e \u0432 \u0431\u0434 (\u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438), \u043d\u043e \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0448\u043b\u043e\u0441\u044c \u0438 \u0434\u043b\u044f UI.<br \/>  \u0412\u043e\u0442, \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0442\u0438\u043f\u0430 \u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/6ec\/a82\/249\/6eca822491a44d0888a2c9af677d063a.png\"\/>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0442\u0438\u043f\u0430 \u0421\u0442\u0440\u043e\u043a\u0430<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/c4c\/3b6\/1f6\/c4c3b61f64e94be587391c32c648f698.png\"\/>  <\/div>\n<\/div>\n<p>  \u0410 \u0432\u043e\u0442, \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u043e\u0434 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0430 React&#8217;\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f\/\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">\/\/\/ &lt;reference path=&quot;..\/..\/references.d.ts&quot;\/&gt;  module DirectCrm {         export interface SaveCustomFieldKindComponentProps extends Model&lt;CustomFieldKindValueBackendViewModel&gt;         {          }          interface SaveCustomFieldKindComponentState         {                 model?: CustomFieldKindValueBackendViewModel;                 validationContext: IValidationContext&lt;CustomFieldKindValueBackendViewModel&gt;;         }          export class SaveCustomFieldKindComponent extends React.Component&lt;SaveCustomFieldKindComponentProps, SaveCustomFieldKindComponentState&gt;         {                 private _componentsMap: ComponentsMap&lt;CustomFieldKindConstantComponentDataBase, CustomFieldKindTypedComponentProps&gt;;                  constructor(props: SaveCustomFieldKindComponentProps)                 {                         super(props);                          this.state = {                                 model: props.model,                                 validationContext: createTypedValidationContext&lt;CustomFieldKindValueBackendViewModel&gt;(props.validationSummary)                         };                         this._componentsMap = ComponentsMap.initialize(this.state.model.componentsMap);                 }                  _setModel = (model: CustomFieldKindValueBackendViewModel) =&gt;                 {                         this.setState({                                 model: model                         });                 }                                  _handleFieldTypeChange = (newFieldType: string) =&gt;                 {                         var clone = _.clone(this.state.model);                          clone.fieldType = newFieldType;                         clone.typedViewModel = {                                 type: newFieldType,                                 $type: this._componentsMap[newFieldType].viewModelType                         };                          this._setModel(clone);                 }                  _getColumnPrefixOrEmptyString = (entityType: string) =&gt;                 {                         var entityTypeDto = _.find(this.props.model.entityTypes, et =&gt; et.systemName === entityType);                         return entityTypeDto && entityTypeDto.prefix || &quot;&quot;;                 }                  _hanleEntityTypeChange = (newEntityType: string) =&gt;                 {                         var clone = _.clone(this.state.model);                          clone.entityType = newEntityType;                         var columnPrefix = this._getColumnPrefixOrEmptyString(newEntityType);                         clone.columnName = `${columnPrefix}${this.state.model.systemName || &quot;&quot;}`;                          this._setModel(clone);                 }                  _handleSystemNameChange = (newSystemName: string) =&gt;                 {                         var clone = _.clone(this.state.model);                          clone.systemName = newSystemName;                         var columnPrefix = this._getColumnPrefixOrEmptyString(this.state.model.entityType);                         clone.columnName = `${columnPrefix}${newSystemName || &quot;&quot;}`;                          this._setModel(clone);                 }                  _renderComponent = () =&gt;                 {                         var entityTypeSelectOptions =                                 this.state.model.entityTypes.map(et =&gt;                                 {                                         return { Text: et.name, Value: et.systemName }                                 });                          var fieldTypeSelectOptions =                                  Object.keys(this._componentsMap).                                 map(key =&gt;                                 {                                         return {                                                 Text: this._componentsMap[key].name,                                                 Value: key                                         };                                 });                          var componentInfo = this._componentsMap[this.state.model.fieldType];                         var TypedComponent = componentInfo.component;                          return (                                 &lt;div&gt;                                         &lt;div className=&quot;row form_horizontal&quot;&gt;                                                 &lt;FormGroup                                                          label=&quot;\u0414\u043b\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438&quot;                                                         validationMessage={this.state.validationContext.getValidationMessageFor(m =&gt; m.entityType)}&gt;                                                         &lt;div className=&quot;form-control&quot;&gt;                                                                 &lt;Select                                                                           value={this.state.model.entityType}                                                                          options={entityTypeSelectOptions}                                                                         width=&quot;normal&quot;                                                                         placeholder=&quot;\u0442\u0438\u043f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438&quot;                                                                         onChange={this._hanleEntityTypeChange} \/&gt;                                                         &lt;\/div&gt;                                                 &lt;\/FormGroup&gt;                                                        &lt;DataGroup label=&quot;\u0418\u043c\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0438&quot; value={this.state.model.columnName} \/&gt;                                                  &lt;FormGroup                                                          label=&quot;\u0418\u043c\u044f&quot;                                                         validationMessage={this.state.validationContext.getValidationMessageFor(m =&gt; m.name)}&gt;                                                         &lt;Textbox                                                                  value={this.state.model.name}                                                                  width=&quot;normal&quot;                                                                 onChange={getPropertySetter(                                                                         this.state.model,                                                                          this._setModel,                                                                         viewModel =&gt; viewModel.name)} \/&gt;                                                 &lt;\/FormGroup&gt;                                                  &lt;FormGroup                                                          label=&quot;\u0421\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0435 \u0438\u043c\u044f&quot;                                                         validationMessage={this.state.validationContext.getValidationMessageFor(m =&gt; m.systemName)}&gt;                                                         &lt;Textbox                                                                  value={this.state.model.systemName}                                                                  width=&quot;normal&quot;                                                                 onChange={this._handleSystemNameChange} \/&gt;                                                 &lt;\/FormGroup&gt;                                                  &lt;FormGroup                                                          label=&quot;\u0422\u0438\u043f \u043f\u043e\u043b\u044f&quot;                                                          validationMessage={this.state.validationContext.getValidationMessageFor(m =&gt; m.fieldType)}&gt;                                                         &lt;div className=&quot;form-control&quot;&gt;                                                                 &lt;Select                                                                           value={this.state.model.fieldType}                                                                          options={fieldTypeSelectOptions}                                                                         width=&quot;normal&quot;                                                                         placeholder=&quot;\u0442\u0438\u043f \u043f\u043e\u043b\u044f&quot;                                                                         onChange={this._handleFieldTypeChange} \/&gt;                                                         &lt;\/div&gt;                                                 &lt;\/FormGroup&gt;                                                                                                  &lt;TypedComponent                                                          validationContext={this.state.validationContext.getValidationContextFor(m =&gt; m.typedViewModel)}                                                         onChange={getPropertySetter(                                                                         this.state.model,                                                                          this._setModel,                                                                         viewModel =&gt; viewModel.typedViewModel)}                                                         value={this.state.model.typedViewModel}                                                         constantComponentData={componentInfo.constantComponentData} \/&gt;                                                  &lt;FormGroup&gt;                                                         &lt;Checkbox                                                                  checked={this.state.model.isMultiple}                                                                 label=&quot;\u041c\u043e\u0436\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u043e\u043b\u0435 \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e&quot;                                                                 onChange={getPropertySetter(                                                                         this.state.model,                                                                          this._setModel,                                                                         viewModel =&gt; viewModel.isMultiple)}                                                                 disabled={false} \/&gt;                                                 &lt;\/FormGroup&gt;                                                                                                  {this._renderShouldBeExportedCheckbox()}                                         &lt;\/div&gt;                                 &lt;\/div&gt;);                 }                  _getViewModelValue = () =&gt;                 {                         var clone = _.clone(this.state.model);                          clone.componentsMap = null;                         clone.entityTypes = null;                          return clone;                 }                  render() {             return (                                 &lt;div&gt;                                         &lt;fieldset&gt;                         {this._renderComponent() }                                         &lt;\/fieldset&gt;                                         &lt;HiddenInputJsonSerializer model={this._getViewModelValue()} name={this.props.modelName} \/&gt;                                 &lt;\/div&gt;);         }                  _renderShouldBeExportedCheckbox = () =&gt;                 {                         if (this.state.model.entityType !== &quot;HistoricalCustomer&quot;)                                 return null;                          return (                                 &lt;FormGroup                                         validationMessage={this.state.validationContext.getValidationMessageFor(m =&gt; m.shouldBeExported)}&gt;                                         &lt;Checkbox                                                  checked={this.state.model.shouldBeExported}                                                 label=&quot;\u0412\u044b\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0435&quot;                                                 onChange={getPropertySetter(                                                         this.state.model,                                                          this._setModel,                                                         viewModel =&gt; viewModel.shouldBeExported)}                                                 disabled={false} \/&gt;                                 &lt;\/FormGroup&gt;);                 }         } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h3>TypeScript<\/h3>\n<p>  \u00ab\u0427\u0442\u043e \u044d\u0442\u043e \u0431\u044b\u043b\u043e?\u00bb \u2014 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0432\u044b, \u0435\u0441\u043b\u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u0438 \u0443\u0432\u0438\u0434\u0435\u0442\u044c javascript. \u042d\u0442\u043e tsx \u2014 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 React&#8217;\u043e\u0432\u043e\u0433\u043e jsx&#8217;\u0430 \u043f\u043e\u0434 TypeScript. \u041d\u0430\u0448 UI \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u00ab\u043c\u0430\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0442\u0440\u043e\u043a\u00bb. \u0421\u043e\u0433\u043b\u0430\u0441\u0438\u0442\u0435\u0441\u044c, \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043e\u0442 \u0442\u0430\u043a\u0438\u0445 \u0445\u0430\u0440\u0434\u043a\u043e\u0440\u043d\u044b\u0445 \u0431\u044d\u043a\u044d\u043d\u0434\u0449\u0438\u043a\u043e\u0432, \u043a\u0430\u043a \u043c\u044b \ud83d\ude42<br \/>  \u0422\u0443\u0442 \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u043e\u0432. \u0423 \u043c\u0435\u043d\u044f \u043d\u0435\u0442 \u0446\u0435\u043b\u0438 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u0445\u043e\u043b\u0438\u0432\u0430\u0440 \u043d\u0430 \u0442\u0435\u043c\u0443 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438- \u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438-\u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432. \u041f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0441\u043b\u043e\u0436\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043b\u044e\u0431\u0438\u0442 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u044f\u0437\u044b\u043a\u0438. \u041c\u044b \u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u043d\u0430 \u043d\u0438\u0445 <s>\u043d\u0435\u043b\u044c\u0437\u044f<\/s> \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u0441\u044f \u0433\u043e\u0434\u0430\u043c\u0438. \u041d\u0443 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e IntelliSense \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \ud83d\ude42 \u0422\u0430\u043a\u043e\u0435 \u0432\u043e\u0442 \u0443 \u043d\u0430\u0441 \u0443\u0431\u0435\u0436\u0434\u0435\u043d\u0438\u0435. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043f\u043e\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0451 \u043f\u043e\u043a\u0440\u044b\u0442\u044c \u0442\u0435\u0441\u0442\u0430\u043c\u0438, \u0438 \u0442\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c, \u043d\u043e \u0441\u043f\u043e\u0440\u0438\u0442\u044c \u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<br \/>  \u0424\u043e\u0440\u043c\u0430\u0442 tsx \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0443\u0434\u0438\u0435\u0439 \u0438 \u043d\u043e\u0432\u044b\u043c R#, \u0447\u0442\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0449\u0451 \u043e\u0434\u043d\u0438\u043c \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u044b\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u043c. \u0410 \u0432\u0435\u0434\u044c \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434 \u0432 \u0441\u0442\u0443\u0434\u0438\u0438 (\u043d\u0435 \u0442\u043e \u0447\u0442\u043e \u0432 R#) \u043d\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0434\u0430\u0436\u0435 jsx&#8217;\u0430, \u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430 js \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0438\u043c\u0435\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 (\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 Sublime \u0438 Atom). \u0412 \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u044b \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u043b\u043e \u0432 \u0441\u0442\u0443\u0434\u0438\u0439\u043d\u043e\u043c Solution&#8217;\u0435, \u0447\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u043e \u0431\u0430\u0442\u0445\u0451\u0440\u0442\u043e\u0432. \u041d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043e\u0431 \u044d\u0442\u043e\u043c, \u0432\u0435\u0434\u044c \u0441\u0447\u0430\u0441\u0442\u044c\u0435 \u0443\u0436\u0435 \u043d\u0430\u0441\u0442\u0443\u043f\u0438\u043b\u043e.<br \/>  \u041d\u0443\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u0430\u0436\u0435 typescript \u0432 \u0447\u0438\u0441\u0442\u043e\u043c \u0432\u0438\u0434\u0435 \u043d\u0435 \u0434\u0430\u0451\u0442 \u0442\u043e\u0442 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432 \u043c\u043e\u0434\u0435\u043b\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e (\u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0431\u0438\u043d\u0434\u0438\u0442\u044c UI-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b \u043d\u0430 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043c\u043e\u0434\u0435\u043b\u0438), \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c callback-\u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u0447\u0442\u043e \u0434\u043e\u043b\u0433\u043e, \u0438 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d callback, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0438\u043c\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u0447\u0442\u043e \u043d\u0438 \u0440\u0430\u0437\u0443 \u043d\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043e. \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u044d\u0442\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0443 \u043d\u0430\u0441 \u0440\u0435\u0448\u0435\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u043a\u043e\u0434\u043e\u043c (\u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0438\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f getPropertySetter \u0432\u044b\u0448\u0435):   <\/p>\n<pre><code class=\"javascript\">\/\/\/ &lt;reference path=&quot;..\/..\/libraries\/underscore.d.ts&quot;\/&gt;  function getPropertySetter&lt;TViewModel, TProperty&gt;(         viewModel: TViewModel,         viewModelSetter: {(viewModel: TViewModel): void},         propertyExpression: {(viewModel: TViewModel): TProperty}): {(newPropertyValue: TProperty): void} {         return (newPropertyValue: TProperty) =&gt;         {                 var viewModelClone = _.clone(viewModel);                 var propertyName = getPropertyNameByPropertyProvider(propertyExpression);                 viewModelClone[propertyName] = newPropertyValue;                 viewModelSetter(viewModelClone);         }; }  function getPropertyName&lt;TObject&gt;(obj: TObject, expression: {(obj: TObject): any}): string {         return getPropertyNameByPropertyProvider(expression); }  function getPropertyNameByPropertyProvider(propertyProvider: Function): string {         return \/\\.([^\\.;]+);?\\s*\\}$\/.exec(propertyProvider.toString())[1]; } <\/code><\/pre>\n<p>  \u041d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043e\u043c\u043d\u0435\u043d\u0438\u0439 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f getPropertyNameByPropertyProvider \u043e\u0447\u0435\u043d\u044c-\u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0440\u0451\u043c\u043d\u0430\u044f (\u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u043e\u0434\u0431\u0435\u0440\u0435\u0448\u044c). \u041d\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0432\u044b\u0431\u043e\u0440\u0430 typescript \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442. ExpressionTree \u0438 nameof \u0432 \u043d\u0451\u043c \u043d\u0435\u0442, \u0430 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b getPropertySetter \u043f\u0435\u0440\u0435\u0432\u0435\u0448\u0438\u0432\u0430\u044e\u0442 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0442\u0430\u043a\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432, \u0447\u0442\u043e \u0441 \u043d\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f? \u041e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0447\u0430\u0442\u044c \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u044c \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442, \u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0443\u0434\u0430 \u043a\u0430\u043a\u043e\u0435-\u043d\u0438\u0431\u0443\u0434\u044c \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0430 \u043c\u043e\u0436\u0435\u0442 \u043a \u0442\u043e\u043c\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c nameof \u0432 typescript \u0441\u0434\u0435\u043b\u0430\u044e\u0442.<br \/>  \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0442\u0430\u043a\u043e\u043c\u0443 <i>\u0445\u0430\u043a\u0443<\/i> \u0443 \u043d\u0430\u0441, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043a\u043e\u0434\u0443 \u0438 \u043d\u0435 \u043d\u0430\u0434\u043e \u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0433\u0434\u0435-\u0442\u043e \u0440\u0430\u0437\u0432\u0430\u043b\u0438\u043b\u043e\u0441\u044c.<br \/>  \u0412 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u043b\u0448\u0435\u0431\u043d\u043e. \u041d\u0435 \u0443\u043a\u0430\u0437\u0430\u043b \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 prop \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430? \u041e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438. \u041f\u0435\u0440\u0435\u0434\u0430\u043b prop \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442? \u041e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u0443\u0440\u0430\u0446\u043a\u0438\u0445 PropTypes \u0441 \u0438\u0445 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f\u043c\u0438 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0442\u0443\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e backend \u0443 \u043d\u0430\u0441 \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u043d\u0430 C#, \u0430 \u043d\u0435 \u043d\u0430 typescript, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u0436\u0434\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0443\u044e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0432\u0430\u0436\u0434\u044b: \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442: \u043c\u044b \u0441\u0430\u043c\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f typescript \u0438\u0437 \u0442\u0438\u043f\u043e\u0432 \u043d\u0430 .NET \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0438 opensource&#8217;\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0441 \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0438\u043b\u0438, \u043d\u043e \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/266899\/\">\u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e<\/a>. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u043a\u0430\u043a-\u043d\u0438\u0431\u0443\u0434\u044c \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u043e\u043d\u0430 \u0441\u0435\u0431\u044f \u0432\u0435\u0434\u0451\u0442 \u0432 \u0431\u043e\u0435\u0432\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445. \u0421\u0443\u0434\u044f \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u0432\u0441\u0451 \u0443\u0436\u0435 \u0445\u043e\u0440\u043e\u0448\u043e.<\/p>\n<h3>\u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/h3>\n<p>  \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e, \u043a\u0430\u043a \u043c\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u0440\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u043a\u0430\u043a \u043e\u043d\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u0421\u0440\u0430\u0437\u0443 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0443, \u0447\u0442\u043e \u043a\u0430\u043f\u043b\u0438\u043d\u0433 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0432\u044b\u0441\u043e\u043a\u0438\u0439, \u043d\u043e \u0447\u0442\u043e \u043f\u043e\u0434\u0435\u043b\u0430\u0442\u044c.<br \/>  \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0435\u0441\u0442\u044c \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0431\u0438\u043d\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u0438 POST-\u0437\u0430\u043f\u0440\u043e\u0441\u0435. \u041e\u0431\u044b\u0447\u043d\u043e \u0442\u0430 \u0436\u0435 \u0441\u0430\u043c\u0430\u044f \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442. \u0412\u043e\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0434 (C#), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439, \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0432\u044b\u0448\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">public void PrepareForViewing(MvcModelContext mvcModelContext) { \tComponentsMap = ModelApplicationHostController \t\t.Instance \t\t.Get&lt;ReactComponentViewModelConfiguration&gt;() \t\t.GetNamedObjectRelatedComponentsMapFor&lt;CustomFieldKindTypedViewModelBase, CustomFieldType&gt;( \t\t\tcustomFieldViewModel =&gt; customFieldViewModel.PrepareForViewing(mvcModelContext));  \tEntityTypes = ModelApplicationHostController.NamedObjects \t\t.GetAll&lt;CustomFieldKindEntityType&gt;() \t\t.Select( \t\t\ttype =&gt; new EntityTypeDto \t\t\t{ \t\t\t\tName = type.Name, \t\t\t\tSystemName = type.SystemName, \t\t\t\tPrefix = type.ColumnPrefix \t\t\t}) \t\t.ToArray();  \tif (ModelApplicationHostController.NamedObjects.Get&lt;DirectCrmFeatureComponent&gt;().Sku.IsEnabled()) \t{ \t\tEntityTypes = \t\t\tEntityTypes.Where( \t\t\t\tet =&gt; et.SystemName != ModelApplicationHostController.NamedObjects \t\t\t\t\t\t\t\t\t\t\t.Get&lt;CustomFieldKindEntityTypeComponent&gt;().Purchase.SystemName) \t\t\t\t.ToArray(); \t} \telse \t{ \t\tEntityTypes = \t\t\tEntityTypes.Where( \t\t\t\tet =&gt; et.SystemName != ModelApplicationHostController.NamedObjects \t\t\t\t\t\t\t\t\t\t\t.Get&lt;CustomFieldKindEntityTypeComponent&gt;().Sku.SystemName) \t\t\t\t.ToArray(); \t}  \tif (FieldType.IsNullOrEmpty()) \t{ \t\tTypedViewModel = new StringCustomFieldKindTypedViewModel(); \t\tFieldType = TypedViewModel.Type; \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0443\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432.<br \/>  \u0427\u0442\u043e\u0431\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u044d\u0442\u043e\u0439 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438, \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043d\u0430\u043f\u0438\u0441\u0430\u043d Extension-\u043c\u0435\u0442\u043e\u0434 HtmlHelper. \u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0432 \u043b\u044e\u0431\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u0433\u0434\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043e\u0434:  <\/p>\n<pre><code class=\"cs\">@Html.ReactJsFor(&quot;DirectCrm.SaveCustomFieldKindComponent&quot;, m =&gt; m.Value) <\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0432\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0438\u043c\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0432\u0442\u043e\u0440\u044b\u043c \u2014 PropertyExpression \u2014 \u043f\u0443\u0442\u044c \u0432\u043e \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0433\u0434\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0412\u043e\u0442 \u043a\u043e\u0434 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430:  <\/p>\n<pre><code class=\"cs\">public static IHtmlString ReactJsFor&lt;TModel, TProperty&gt;( \tthis HtmlHelper&lt;TModel&gt; htmlHelper, \tstring componentName, \tExpression&lt;Func&lt;TModel, TProperty&gt;&gt; expression, \tobject initializeObject = null) { \tvar validationData = htmlHelper.JsonValidationMessagesFor(expression); \tvar metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); \tvar modelData = JsonConvert.SerializeObject( \t\tmetadata.Model, \t\tnew JsonSerializerSettings \t\t{ \t\t\tTypeNameHandling = TypeNameHandling.Auto, \t\t\tTypeNameAssemblyFormat = FormatterAssemblyStyle.Full, \t\t\tConverters = \t\t\t{ \t\t\t\tnew StringEnumConverter() \t\t\t} \t\t}); \tvar initializeData = JsonConvert.SerializeObject(initializeObject);  \treturn new HtmlString(string.Format( \t\t&quot;&lt;div data-react-component='{0}' data-react-model-name='{1}' data-react-model='{2}' &quot; + \t\t\t&quot;data-react-validation-summary='{3}' data-react-initialize='{4}'&gt;&lt;\/div&gt;&quot;, \t\tHttpUtility.HtmlEncode(componentName), \t\tHttpUtility.HtmlEncode(htmlHelper.NameFor(expression)), \t\tHttpUtility.HtmlEncode(modelData), \t\tHttpUtility.HtmlEncode(validationData), \t\tHttpUtility.HtmlEncode(initializeData))); } <\/code><\/pre>\n<p>  \u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c div, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u0445 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430: \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043f\u0443\u0442\u044c \u0432 \u0431\u043e\u043b\u0435\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0437\u0430 \u0441\u0447\u0451\u0442 \u043d\u0435\u0445\u0438\u0442\u0440\u043e\u0433\u043e \u0432 \u044d\u0442\u043e\u0442 div \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0435\u043d\u0434\u0435\u0440\u0435\u043d \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442:  <\/p>\n<pre><code class=\"javascript\">function initializeReact(context) { \t$('div[data-react-component]', context).each(function () { \t\tvar that = this;  \t\tvar data = $(that).data(); \t\tvar component = eval(data.reactComponent);  \t\tif (data.reactInitialize == null) { \t\t\tdata.reactInitialize = {}; \t\t}  \t\tvar props = $.extend({ \t\t\tmodel: data.reactModel, \t\t\tvalidationSummary: data.reactValidationSummary, \t\t\tmodelName: data.reactModelName \t\t}, data.reactInitialize);  \t\tReact.render( \t\t\tReact.createElement(component, props), \t\t\tthat \t\t); \t}); } <\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u044f\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u2014 \u0442\u043e \u0435\u0441\u0442\u044c \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0438\u043c\u0435\u043d\u043d\u043e \u0443 \u044d\u0442\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432\u043e\u043e\u0431\u0449\u0435 \u0435\u0441\u0442\u044c state. \u0412\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0436\u0435 \u0432 \u043d\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u043b\u0438\u0431\u043e \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432\u043e\u043e\u0431\u0449\u0435, \u043b\u0438\u0431\u043e \u0438\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0430\u0436\u043d\u044b\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (\u043a\u0430\u043a \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0444\u043b\u0430\u0433 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438\/\u0437\u0430\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u0430\u0434\u0430\u044e\u0449\u0435\u0433\u043e \u043c\u0435\u043d\u044e \u0432 select&#8217;\u0435).<\/p>\n<h3>Binding<\/h3>\n<p>  \u041f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e, \u043c\u044b \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043d\u043e \u043a\u0430\u043a \u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440? <br \/>  \u0412\u0441\u0451 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0438. \u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u043e\u0441\u0442 \u0444\u043e\u0440\u043c\u044b. \u0423 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u043e\u0432 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445 \u043d\u0435\u0442 \u0438\u043c\u0451\u043d, \u0438 \u0431\u0438\u043d\u0434\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0441\u0447\u0451\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 (\u0430 \u043e\u043d \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u0441\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043a\u0430\u043a \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0432\u044b\u0448\u0435), \u043f\u0435\u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 hidden input, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438, \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0432 json. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0442 json \u0431\u0438\u043d\u0434\u0438\u043b\u0441\u044f \u043d\u0430 \u043d\u0430\u0448\u0435 ASP.NET \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0431\u044b\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 ModelBinder.<br \/>  \u041d\u0430\u0447\u043d\u0451\u043c \u0441 hidden input&#8217;\u0430. \u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442:  <\/p>\n<pre><code class=\"javascript\">&lt;HiddenInputJsonSerializer model={this._getViewModelValue() } name={this.props.modelName} \/&gt; <\/code><\/pre>\n<p>  \u0415\u0433\u043e \u043a\u043e\u0434 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442:  <\/p>\n<pre><code class=\"javascript\">class HiddenInputJsonSerializer extends React.Component&lt;{ model: any, name: string }, {}&gt; { \trender() { \t    var json = JSON.stringify(this.props.model); \t\tvar name = this.props.name;  \t\treturn ( \t\t\t&lt;input type=&quot;hidden&quot; value={json} name={name} \/&gt; \t\t); \t} } <\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u043f\u043e\u0441\u0442\u0435 \u0444\u043e\u0440\u043c\u044b \u043c\u044b \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0441\u0442\u0438\u043c \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0439 json \u0441 \u0438\u043c\u0435\u043d\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0432 this.props.modelName \u2014 \u0430 \u044d\u0442\u043e \u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043c\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0432 data-react-model-name \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 (\u0441\u043c. \u0432\u044b\u0448\u0435), \u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u043f\u0443\u0442\u044c \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043e \u043d\u0430\u0448\u0435\u0439 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0435\u0434\u0435\u0442 json&#8217;\u043e\u043c.<br \/>  \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0442 json \u0441\u0431\u0438\u043d\u0434\u0438\u043b\u0441\u044f \u043d\u0430 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430, \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438\u0437 json&#8217;\u0430, \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c JsonBindedAttribute. \u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043a\u043e\u0434 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u043b\u043e\u0436\u0435\u043d\u0430 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0431\u0438\u043d\u0434\u0438\u0442\u044c\u0441\u044f \u0438\u0437 json:  <\/p>\n<pre><code class=\"cs\">public class CustomFieldKindCreatePageViewModel : AdministrationSiteMasterViewModel { \tpublic CustomFieldKindCreatePageViewModel() \t{ \t\tValue = new CustomFieldKindValueViewModel(); \t}  \t[JsonBinded] \tpublic CustomFieldKindValueViewModel Value { get; set; }  \t\/\/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 } <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0447\u0442\u043e-\u0442\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u0438 \u043f\u044b\u0442\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e CustomFieldKindCreatePageViewModel.Value \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438. \u042d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u2014 ModelBinder. \u041a\u043e\u0434 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043b\u043e\u0433\u0438\u0447\u0435\u043d: \u0435\u0441\u043b\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043e JsonBindedAttribute \u2014 \u043d\u0430\u0439\u0442\u0438 \u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u043a\u0430\u043a CustomFieldKindValueViewModel (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435). \u0412\u043e\u0442 \u0435\u0433\u043e \u043a\u043e\u0434:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u0431\u0438\u043d\u0434\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442 json<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">public class MindboxDefaultModelBinder : DefaultModelBinder { \tprivate object DeserializeJson( \t\tstring json, \t\tType type,  \t\tstring fieldNamePrefix, \t\tModelBindingContext bindingContext, \t\tControllerContext controllerContext) \t{ \t\tvar settings = new JsonSerializerSettings \t\t{ \t\t\tTypeNameHandling = TypeNameHandling.Auto, \t\t\tMetadataPropertyHandling = MetadataPropertyHandling.ReadAhead, \t\t\tConverters = new JsonConverter[] \t\t\t{ \t\t\t\tnew ReactComponentPolimorphicViewModelConverter(), \t\t\t\tnew FormBindedConverter(controllerContext, bindingContext, fieldNamePrefix) \t\t\t} \t\t};  \t\treturn JsonConvert.DeserializeObject(json, type, settings); \t}  \tprotected override void BindProperty( \t\tControllerContext controllerContext, \t\tModelBindingContext bindingContext, \t\tPropertyDescriptor propertyDescriptor) \t{ \t\tif (!propertyDescriptor.Attributes.OfType&lt;JsonBindedAttribute&gt;().Any()) \t\t{ \t\t\tbase.BindProperty(controllerContext, bindingContext, propertyDescriptor); \t\t} \t}  \tpublic override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) \t{ \t\tvar result = base.BindModel(controllerContext, bindingContext);  \t\t\/\/ ... \t\t\/\/ \u043a\u043e\u0434, \u043d\u0435 \u0438\u043c\u0435\u044e\u0449\u0438\u0439 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043a \u0434\u0435\u043b\u0443 \t\t\/\/ ...  \t\tif (result != null) \t\t{ \t\t\tFillJsonBindedProperties(controllerContext, bindingContext, result); \t\t}  \t\treturn result; \t}  \tprivate static string BuildFormVariableFullName(string modelName, string formVariableName) \t{ \t\treturn modelName.IsNullOrEmpty() ? formVariableName : string.Format(&quot;{0}.{1}&quot;, modelName, formVariableName); \t}  \tprivate void FillJsonBindedProperties( \t\tControllerContext controllerContext, \t\tModelBindingContext bindingContext, \t\tobject result) \t{ \t\tvar jsonBindedProperties = result.GetType().GetProperties() \t\t\t\t.Where(pi =&gt; pi.HasCustomAttribute&lt;JsonBindedAttribute&gt;()) \t\t\t\t.ToArray();  \t\tforeach (var propertyInfo in jsonBindedProperties) \t\t{ \t\t\tvar formFieldFullName = BuildFormVariableFullName( \t\t\t\tbindingContext.FallbackToEmptyPrefix ? string.Empty : bindingContext.ModelName, \t\t\t\tpropertyInfo.Name);  \t\t\tif (controllerContext.HttpContext.Request.Params.AllKeys.Contains(formFieldFullName)) \t\t\t{ \t\t\t\tvar json = controllerContext.HttpContext.Request.Params[formFieldFullName]; \t\t\t\tif (!json.IsNullOrEmpty()) \t\t\t\t{ \t\t\t\t\tvar convertedObject = DeserializeJson( \t\t\t\t\t\tjson, propertyInfo.PropertyType, formFieldFullName, bindingContext, controllerContext);  \t\t\t\t\tpropertyInfo.SetValue(result, convertedObject); \t\t\t\t} \t\t\t} \t\t\telse \t\t\t{ \t\t\t\tthrow new InvalidOperationException( \t\t\t\t\tstring.Format( \t\t\t\t\t\t&quot;\u041d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0431\u0438\u043d\u0434\u0435\u0440 \u0434\u043b\u044f property {0} \u0438\u0437 \u0442\u0438\u043f\u0430 {1}. \u0412 99.9% \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u0432 js.&quot;, \t\t\t\t\t\tformFieldFullName, \t\t\t\t\t\tresult.GetType().AssemblyQualifiedName)); \t\t\t} \t\t} \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u043e\u0436\u0438\u0434\u0430\u043b\u0438, \u0447\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0431\u0443\u0434\u0435\u0442 \u0431\u0438\u043d\u0434\u0438\u0442\u044c\u0441\u044f \u0438\u0437 json, \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c json \u043d\u0435 \u043f\u0440\u0438\u0448\u0451\u043b, \u043c\u044b \u0443\u043f\u0430\u0434\u0451\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0441 99.9% \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0431\u044b\u043b \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0435\u043d. \u041b\u0438\u0431\u043e \u043c\u044b \u043e\u0448\u0438\u0431\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u043f\u0440\u043e\u0441\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0438 \u0438\u043c\u0435\u043d\u0438 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043d\u043e \u0442\u0430\u043a\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u043e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<br \/>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432 \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u044c\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u044e \u043a\u043e\u0434\u043e\u0432\u0443\u044e \u0431\u0430\u0437\u0443 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 html, \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0438 react-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b <i>\u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e<\/i>. \u0411\u044b\u0432\u0430\u044e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d react&#8217;\u043e\u043c, \u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0433\u043e \u043a\u0443\u0441\u043e\u0447\u043a\u0430 \u0447\u0430\u0441\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0433\u043e \u043a\u0443\u0441\u043e\u0447\u043a\u0430 \u0447\u0430\u0441\u0442\u044c \u0441\u043d\u043e\u0432\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f react&#8217;\u043e\u043c. \u0422\u0430\u043a\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430. \u042f \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043b \u0435\u0451 \u0432\u044b\u0448\u0435, \u043d\u043e \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0435\u0451 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u0435\u0449\u0451 \u0440\u0430\u0437 \u0442\u0443\u0442:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/b32\/481\/9cf\/b324819cfd044abc8817319b04428926.png\"\/>  <\/div>\n<\/div>\n<p>  \u0412\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c, \u043e\u0434\u043d\u0430\u043a\u043e \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0440\u0435\u043b\u043a\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u00ab\u0424\u0438\u043b\u044c\u0442\u0440\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0434\u0435\u043b\u0430\u043d \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u043c js \u0435\u0449\u0451 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434, \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 react \u2014 \u0437\u0430\u0434\u0430\u0447\u0430, \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0432 \u043c\u0435\u0441\u044f\u0446. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c js, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0444\u0438\u043b\u044c\u0442\u0440, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 html \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0430 js \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u0449\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430. \u041e\u0434\u043d\u0430\u043a\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0444\u0438\u043b\u044c\u0442\u0440 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043d\u0430\u0431\u043e\u0440\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u043f\u043e\u043c\u0435\u043d\u044c\u0448\u0435, \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u043c UI-\u0435\u043c, \u043d\u0443\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f react. \u0412\u0442\u043e\u0440\u0430\u044f \u0441\u0442\u0440\u0435\u043b\u043a\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0444\u0438\u043b\u044c\u0442\u0440 \u043f\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u00ab\u0428\u0430\u0431\u043b\u043e\u043d \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u00bb, \u043e\u043d \u0441\u0434\u0435\u043b\u0430\u043d, \u043a\u0430\u043a react&#8217;\u043e\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442. <br \/>  \u041a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0431\u0438\u043d\u0434\u0438\u043d\u0433 \u0442\u0430\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b? \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e input&#8217;\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d name, \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u043a\u043e\u0442\u043e\u0440\u0433\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u043e\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 react. \u041e\u0434\u0438\u043d \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 input&#8217;\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0448\u0435\u043c hidden input&#8217;\u043e\u043c, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043a\u0430\u043a\u043e\u0433\u043e-\u043b\u0438\u0431\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u043e\u0432, \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0435 \u0432 POST-\u0437\u0430\u043f\u0440\u043e\u0441\u0435, \u0431\u044b\u043b\u0438 \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u0430 JsonBindedAttribute, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043e\u043d\u0430 \u0438 \u0432\u0441\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0432 \u043d\u0435\u0451 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0438\u0437 json. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u044b, \u0435\u0451 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043e FormBindedAttribute, \u0430 \u043f\u0440\u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0437 json \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c FormBindedConverter, \u043a\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043d\u0438\u0436\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 FormBindedConverter<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">public class FormBindedConverter : JsonConverter { \tprivate readonly ControllerContext controllerContext;  \tprivate readonly ModelBindingContext parentBindingContext;  \tprivate readonly string formNamePrefix;  \tprivate Type currentType = null;  \tprivate static readonly Type[] primitiveTypes = new[] \t{ \t\ttypeof(int), \t\ttypeof(bool), \t\ttypeof(long), \t\ttypeof(decimal), \t\ttypeof(string) \t};  \tpublic FormBindedConverter( \t\tControllerContext controllerContext, \t\tModelBindingContext parentBindingContext, \t\tstring formNamePrefix) \t{ \t\tthis.controllerContext = controllerContext; \t\tthis.parentBindingContext = parentBindingContext; \t\tthis.formNamePrefix = formNamePrefix; \t}  \tpublic override bool CanConvert(Type objectType) \t{ \t\treturn currentType != objectType && !primitiveTypes.Contains(objectType); \t}  \tpublic override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) \t{ \t\tvar currentJsonPath = reader.Path;  \t\tcurrentType = objectType; \t\tvar result = serializer.Deserialize(reader, objectType); \t\tcurrentType = null;  \t\tif (result == null) \t\t\treturn null;  \t\tvar resultType = result.GetType(); \t\tvar formBindedProperties = resultType.GetProperties().Where(p =&gt; p.HasCustomAttribute&lt;FormBindedAttribute&gt;()); \t\tforeach (var formBindedProperty in formBindedProperties) \t\t{ \t\t\tvar formBindedPropertyName = formBindedProperty.Name; \t\t\tvar formBindedPropertyFullPath = $&quot;{formNamePrefix}.{currentJsonPath}.{formBindedPropertyName}&quot;;  \t\t\tvar formBindedPropertyModelBinderAttribute = \t\t\t\tformBindedProperty.PropertyType.TryGetSingleAttribute&lt;ModelBinderAttribute&gt;();  \t\t\tvar effectiveBinder = GetBinder(formBindedPropertyModelBinderAttribute); \t\t\tvar formBindedObject = effectiveBinder.BindModel( \t\t\t\tcontrollerContext, \t\t\t\tnew ModelBindingContext(parentBindingContext) \t\t\t\t{ \t\t\t\t\tModelMetadata = ModelMetadataProviders.Current.GetMetadataForType( \t\t\t\t\t\t() =&gt; formBindedProperty.GetValue(result), \t\t\t\t\t\tformBindedProperty.PropertyType), \t\t\t\t\tModelName = formBindedPropertyFullPath \t\t\t\t});  \t\t\tformBindedProperty.SetValue(result, formBindedObject); \t\t}  \t\treturn result; \t}  \tprivate static IModelBinder GetBinder(ModelBinderAttribute formBindedPropertyModelBinderAttribute) \t{ \t\tIModelBinder effectiveBinder; \t\tif (formBindedPropertyModelBinderAttribute == null) \t\t{ \t\t\teffectiveBinder = new MindboxDefaultModelBinder(); \t\t} \t\telse \t\t{ \t\t\teffectiveBinder = formBindedPropertyModelBinderAttribute.GetBinder(); \t\t}  \t\treturn effectiveBinder; \t}  \tpublic override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) \t{ \t\tserializer.Serialize(writer, value); \t} } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u042d\u0442\u043e\u0442 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043f\u0440\u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0437 json, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u0435 \u0442\u0438\u043f\u044b \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 FormBindedAttribute. \u0415\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c, \u0442\u043e \u043c\u044b \u0432\u044b\u044f\u0441\u043d\u044f\u0435\u043c, \u043a\u0430\u043a\u043e\u0439 binder \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u044b, \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 binder \u0438 \u043f\u0440\u043e\u0441\u0438\u043c \u0435\u0433\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e. <br \/>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0440\u0438 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u0432 MindboxDefaultModelBinder, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u0432 FormBindedConverter, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u0432 FilterViewModelBinder, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043d\u043e\u0432\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u0432 MindboxDefaultModelBinder.<\/p>\n<h3>\u041f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0435 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c UI \u0447\u0430\u0441\u0442\u043e \u0431\u044b\u0432\u0430\u0435\u0442 \u0442\u0430\u043a, \u0447\u0442\u043e \u043e\u0442 \u0432\u044b\u0431\u043e\u0440\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u0430\u0434\u0430\u044e\u0449\u0435\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u043e\u0437\u044c\u043c\u0451\u043c \u0432\u0441\u0451 \u0442\u0443 \u0436\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/717\/f00\/787\/717f00787659486b8931db5004c79745.png\"\/>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/a38\/cbc\/88e\/a38cbc88e0cb4772ac0ac6baab4a55d2.png\"\/>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/bec\/e74\/c88\/bece74c8850b45f1826a6caa2f86c294.png\"\/>  <\/div>\n<\/div>\n<p>  \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0438\u043f\u0430 \u043f\u043e\u043b\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0439 UI. \u0422\u0430\u043a\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c, \u043d\u0430\u043f\u0438\u0441\u0430\u0432 switch \u043f\u043e \u0442\u0438\u043f\u0430\u043c \u043f\u043e\u043b\u0435\u0439, \u043d\u043e \u043c\u043d\u0435 \u043f\u043e \u0434\u0443\u0448\u0435 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434. \u0412 \u0438\u0442\u043e\u0433\u0435, \u0434\u043b\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0432\u044b\u043f\u0430\u0434\u0430\u043b\u043e\u043a \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043d\u0435\u0439 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u043a\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0412\u043e\u0442 \u043a\u043e\u0434 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432:  <\/p>\n<pre><code class=\"javascript\">module DirectCrm {     export class StringCustomFieldKindComponent extends CustomFieldKindComponentBase {         render() {             var stringViewModel = this.props.value as StringCustomerFieldKindTypedBackendViewModel;             var stringConstantData = this.props.constantComponentData as StringCustomFieldKindConstantComponentData;             var validationContext = this.props.validationContext as IValidationContext&lt;StringCustomerFieldKindTypedBackendViewModel&gt;;              return (                 &lt;div&gt;                     {super.render() }                 &lt;FormGroup                     label=&quot;\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e&quot;                     validationMessage={validationContext.getValidationMessageFor(m =&gt; m.validationStrategySystemName) } &gt;                     &lt;div className=&quot;form-control&quot;&gt;                         &lt;Commons.Select                             value={stringViewModel.validationStrategySystemName}                             width=&quot;normal&quot;                             onChange={getPropertySetter(                                 stringViewModel,                                 vm =&gt; this.props.onChange(vm),                                 m =&gt; m.validationStrategySystemName) }                             options={stringConstantData.validationStrategies}                             disabled={this.props.disabled}\/&gt;                         &lt;\/div&gt;                     &lt;\/FormGroup&gt;                     &lt;\/div&gt;);         }     } } <\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"javascript\">module DirectCrm {     export class DefaultCustomFieldKindComponent extends CustomFieldKindComponentBase {     } } <\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"javascript\">module DirectCrm {     export class CustomFieldKindComponentBase extends React.Component&lt;DirectCrm.CustomFieldKindTypedComponentProps, {}&gt; {         render() {             return &lt;FormGroup                 label = &quot;\u0422\u0438\u043f \u043f\u043e\u043b\u044f&quot;                 validationMessage = { this.props.validationMessageForFieldType } &gt; \t\t\t\t\t&lt;div className=&quot;form-control&quot;&gt;                         &lt;Commons.Select                             value={this.props.fieldType}                             options={this.props.fieldTypeSelectOptions}                             width=&quot;normal&quot;                             placeholder=&quot;\u0442\u0438\u043f \u043f\u043e\u043b\u044f&quot;                             onChange={this.props.handleFieldTypeChange}                             disabled = {this.props.disabled}\/&gt;                 &lt;\/div&gt;                 {this.renderTooltip() }                 &lt;\/FormGroup&gt;         }          renderTooltip() {             return &lt;Commons.Tooltip \t\t\t\tadditionalClasses=&quot;tooltip-icon_help&quot; \t\t\t\tmessage={this.props.constantComponentData.tooltipMessage }\/&gt;         }     } } <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0436\u0435 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430?<br \/>  \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u043a\u043e\u0434\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432\u0441\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0437\u0434\u0435\u0441\u044c \u0435\u0449\u0451 \u0440\u0430\u0437:  <\/p>\n<pre><code class=\"javascript\">_renderComponent = () =&gt; { \tvar fieldTypeSelectOptions = \t\tObject.keys(this._componentsMap). \t\t\tmap(key =&gt; { \t\t\t\treturn { \t\t\t\t\tText: this._componentsMap[key].name, \t\t\t\t\tValue: key \t\t\t\t}; \t\t\t});  \tvar componentInfo = this._componentsMap[this.state.model.fieldType]; \tvar TypedComponent = componentInfo.component;  \treturn ( \t\t&lt;div&gt; \t\t\t&lt;div className=&quot;row form_horizontal&quot;&gt; \t\t\t\t&lt;div className=&quot;col-group&quot;&gt; \t\t\t\t\t\/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b  \t\t\t\t\t&lt;TypedComponent \t\t\t\t\t\tvalidationContext={this.state.validationContext.getValidationContextFor(m =&gt; m.typedViewModel) } \t\t\t\t\t\tonChange={getPropertySetter( \t\t\t\t\t\t\tthis.state.model, \t\t\t\t\t\t\tthis._setModel, \t\t\t\t\t\t\tviewModel =&gt; viewModel.typedViewModel) } \t\t\t\t\t\tvalue={this.state.model.typedViewModel} \t\t\t\t\t\tfieldType={this.state.model.fieldType} \t\t\t\t\t\tvalidationMessageForFieldType={this.state.validationContext.getValidationMessageFor(m=&gt; m.fieldType) } \t\t\t\t\t\tfieldTypeSelectOptions={fieldTypeSelectOptions} \t\t\t\t\t\thandleFieldTypeChange={this._handleFieldTypeChange} \t\t\t\t\t\tconstantComponentData={componentInfo.constantComponentData} \t\t\t\t\t\tdisabled={!this.state.model.isNew}\/&gt; \t\t\t\t&lt;\/div&gt;  \t\t\t\t\/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \t\t&lt;\/div&gt;); } <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u0438\u0437 \u043a\u043e\u0434\u0430, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043d\u0435\u043a\u043e\u0433\u043e TypedComponent, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u043f\u0443\u0442\u0451\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c _componentsMap. \u042d\u0442\u043e\u0442 _componentsMap \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043b\u043e\u0432\u0430\u0440\u044c, \u0433\u0434\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c \u0442\u0438\u043f\u0430 (\u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c \u0432 \u0432\u044b\u043f\u0430\u0434\u0430\u043b\u043a\u0435 \u00ab\u0442\u0438\u043f \u043f\u043e\u043b\u044f\u00bb) \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u044b componentInfo, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430: \u0441\u0430\u043c\u0430 \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0441\u043f\u0438\u0441\u043a\u0438, url-\u044b \u0434\u043e \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432), \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 .NET \u0442\u0438\u043f\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u0443\u044e \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 _componentsMap \u0432 json \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u043d\u0438\u0436\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 ComponentsMap&#39;\u0430<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">&quot;componentsMap&quot;:{         &quot;Integer&quot;:{            &quot;name&quot;:&quot;\u0426\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439&quot;,          &quot;viewModelType&quot;:&quot;Itc.DirectCrm.Web.IntegerCustomFieldKindTypedViewModel, itc.DirectCrm.Web, Version=6.459.0.3741, Culture=neutral, PublicKeyToken=null&quot;,          &quot;componentName&quot;:&quot;DirectCrm.DefaultCustomFieldKindComponent&quot;,          &quot;constantComponentData&quot;:{               &quot;$type&quot;:&quot;Itc.DirectCrm.Web.IntegerCustomFieldKindTypedViewModel, itc.DirectCrm.Web, Version=6.459.0.3741, Culture=neutral, PublicKeyToken=null&quot;,             &quot;tooltipMessage&quot;:&quot;\u041f\u0440\u0438\u043c\u0435\u0440: 123456&quot;,             &quot;type&quot;:&quot;Integer&quot;          }       },       &quot;String&quot;:{            &quot;name&quot;:&quot;\u0421\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0439&quot;,          &quot;viewModelType&quot;:&quot;Itc.DirectCrm.Web.StringCustomFieldKindTypedViewModel, itc.DirectCrm.Web, Version=6.459.0.3741, Culture=neutral, PublicKeyToken=null&quot;,          &quot;componentName&quot;:&quot;DirectCrm.StringCustomFieldKindComponent&quot;,          &quot;constantComponentData&quot;:{               &quot;$type&quot;:&quot;Itc.DirectCrm.Web.StringCustomFieldKindTypedViewModel, itc.DirectCrm.Web, Version=6.459.0.3741, Culture=neutral, PublicKeyToken=null&quot;,             &quot;validationStrategies&quot;:[                  {                     &quot;Disabled&quot;:false,                   &quot;Group&quot;:null,                   &quot;Selected&quot;:true,                   &quot;Text&quot;:&quot;\u0411\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439&quot;,                   &quot;Value&quot;:&quot;Default&quot;                },                {                     &quot;Disabled&quot;:false,                   &quot;Group&quot;:null,                   &quot;Selected&quot;:false,                   &quot;Text&quot;:&quot;\u0411\u0443\u043a\u0432\u044b \u043b\u0430\u0442\u0438\u043d\u0441\u043a\u043e\u0433\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0430 \u0438 \u043f\u0440\u043e\u0431\u0435\u043b\u044b&quot;,                   &quot;Value&quot;:&quot;IsValidLatinStringWithWhitespaces&quot;                },                {                     &quot;Disabled&quot;:false,                   &quot;Group&quot;:null,                   &quot;Selected&quot;:false,                   &quot;Text&quot;:&quot;\u0411\u0443\u043a\u0432\u044b \u043b\u0430\u0442\u0438\u043d\u0441\u043a\u043e\u0433\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0430 \u0438 \u0446\u0438\u0444\u0440\u044b&quot;,                   &quot;Value&quot;:&quot;IsValidLatinStringWithDigits&quot;                },                {                     &quot;Disabled&quot;:false,                   &quot;Group&quot;:null,                   &quot;Selected&quot;:false,                   &quot;Text&quot;:&quot;\u0426\u0438\u0444\u0440\u044b&quot;,                   &quot;Value&quot;:&quot;IsValidDigitString&quot;                }             ],             &quot;validationStrategySystemName&quot;:&quot;Default&quot;,             &quot;tooltipMessage&quot;:&quot;\u041f\u0440\u0438\u043c\u0435\u0440: \\&quot;\u043f\u0440\u0438\u043c\u0435\u0440\\&quot;&quot;,             &quot;type&quot;:&quot;String&quot;          }       },       &quot;Enum&quot;:{            &quot;name&quot;:&quot;\u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435&quot;,          &quot;viewModelType&quot;:&quot;Itc.DirectCrm.Web.EnumCustomFieldKindTypedViewModel, itc.DirectCrm.Web, Version=6.459.0.3741, Culture=neutral, PublicKeyToken=null&quot;,          &quot;componentName&quot;:&quot;DirectCrm.EnumCustomFieldKindComponent&quot;,          &quot;constantComponentData&quot;:{               &quot;$type&quot;:&quot;Itc.DirectCrm.Web.EnumCustomFieldKindTypedViewModel, itc.DirectCrm.Web, Version=6.459.0.3741, Culture=neutral, PublicKeyToken=null&quot;,             &quot;selectedEnumValues&quot;:null,             &quot;forceCreateEnumValue&quot;:false,             &quot;tooltipMessage&quot;:&quot;\u041f\u0440\u0438\u043c\u0435\u0440: \u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 - \\&quot;ExternalId\\&quot;, \u0418\u043c\u044f - \\&quot;\u0422\u0435\u0441\u0442123\\&quot;&quot;,             &quot;type&quot;:&quot;Enum&quot;          }       }    } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u0442\u043e \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043b\u043e\u0432\u0430\u0440\u044c? \u041e\u043d \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u0412\u043e\u0442 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 ComponentsMap \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435:  <\/p>\n<pre><code class=\"cs\">public void PrepareForViewing(MvcModelContext mvcModelContext) { \tComponentsMap = ModelApplicationHostController \t\t.Instance \t\t.Get&lt;ReactComponentViewModelConfiguration&gt;() \t\t.GetNamedObjectRelatedComponentsMapFor&lt;CustomFieldKindTypedViewModelBase, CustomFieldType&gt;( \t\t\tcustomFieldViewModel =&gt; customFieldViewModel.PrepareForViewing(mvcModelContext));  \t\/\/ \u0435\u0449\u0451 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f } <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b ReactComponentViewModelConfiguration \u0437\u043d\u0430\u043b\u0430, \u043a\u0430\u043a\u0438\u0435 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 CustomFieldKindTypedViewModelBase, \u0438\u0445 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041a\u043e\u0434 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u0445\u0438\u0442\u0440\u043e:  <\/p>\n<pre><code class=\"cs\">configuration.RegisterNamedObjectRelatedViewModel&lt;CustomFieldKindTypedViewModelBase, CustomFieldType&gt;( \t() =&gt; new StringCustomFieldKindTypedViewModel()); configuration.RegisterNamedObjectRelatedViewModel&lt;CustomFieldKindTypedViewModelBase, CustomFieldType&gt;( \t() =&gt; new IntegerCustomFieldKindTypedViewModel()); configuration.RegisterNamedObjectRelatedViewModel&lt;CustomFieldKindTypedViewModelBase, CustomFieldType&gt;( \t() =&gt; new EnumCustomFieldKindTypedViewModel()); <\/code><\/pre>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u044d\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u0446\u044b \u0432 C# \u043a\u043e\u0434\u0435. \u041a\u0430\u043a \u044f \u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u043a\u0430\u043f\u043b\u0438\u043d\u0433 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0432\u044b\u0441\u043e\u043a\u0438\u0439.<\/p>\n<h3>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f<\/h3>\n<p>  \u0412 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432:   <\/p>\n<ul>\n<li>\u043c\u044b \u0441\u0430\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043f\u043e\u0434\u0440\u044f\u0434\u0447\u0438\u043a\u043e\u0432<\/li>\n<li>\u043d\u0430\u0448\u0438 \u043f\u043e\u0434\u0440\u044f\u0434\u0447\u0438\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043d\u0430\u0448\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u044b<\/li>\n<li>\u043d\u0430\u0448 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0430\u0439\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445<\/li>\n<\/ul>\n<p>  \u0412\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u043d\u0430\u0448\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u043a\u043e\u043d\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c. \u042d\u0442\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0430\u043c\u043e\u0439 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0440\u0430\u0437\u043d\u043e\u0432\u0438\u0434\u043d\u043e\u0441\u0442\u044c\u044e <a href=\"http:\/\/martinfowler.com\/eaaDev\/Notification.html\">\u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u041d\u043e\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f<\/a>. \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u043d\u0430\u0448\u0435\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0432\u044f\u0442\u0438\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e, \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0443 \u0435\u0451 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c. \u0421\u043a\u0430\u0436\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u0430 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0438\u0445 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442. \u0422\u0430\u043a \u0436\u0435 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u043a\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0440\u044f\u0434\u043e\u043c \u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0430\u043c\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u043c\u0438 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.<br \/>  \u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438. \u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0435\u0437\u0436\u0430\u044e\u0442 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0440\u0438 \u0435\u0433\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0435 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432 data-react-validation-summary (\u0441\u043c. \u043a\u043e\u0434 ReactJsFor \u0432\u044b\u0448\u0435). Validation summary \u2014 \u044d\u0442\u043e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0447\u0435\u0441\u043a\u0438\u0439 json, \u0433\u0434\u0435 \u0438\u043c\u0435\u043d\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 (\u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0435\u0441\u0442\u044c), \u043b\u0438\u0431\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0435\u0439. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u043f\u043e\u043a\u0430\u0436\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 validationSummary \u0434\u043b\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0435 \u043d\u0438\u0436\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041d\u0435\u0443\u0434\u0430\u0447\u043d\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/94d\/7f1\/aa8\/94d7f1aa89b74f5bba745a1134b3fd42.png\"\/>  <\/div>\n<\/div>\n<p>  \u0412\u0451\u0440\u0442\u043a\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0432\u0430\u043b\u0438\u043b\u0430\u0441\u044c, \u043d\u043e \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438.<br \/>  \u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 validation summary \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f:  <\/p>\n<pre><code class=\"javascript\">{      &quot;typedViewModel&quot;:{         &quot;selectedEnumValues[0]&quot;:{            &quot;systemName&quot;:[               &quot;\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043a\u043e\u0440\u043e\u0447\u0435 250 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432&quot;          ]       }    },    &quot;name&quot;:[         &quot;\u0418\u043c\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e&quot;    ] } <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u2014 \u0443\u043c\u0435\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0443, \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0435\u0441\u0442\u044c. \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f ValidationContext, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f validation summary, \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441:  <\/p>\n<pre><code class=\"javascript\">interface IValidationContext&lt;TViewModel&gt; { \tisValid: boolean; \tgetValidationMessageFor: { (propertyExpression: {(model: TViewModel):any}): JSX.Element }; \tvalidationMessageExpandedFor: { (propertyExpression: {(model: TViewModel):any}): JSX.Element }; \tgetValidationContextFor: { &lt;TProperty&gt;(propertyExpression: {(model: TViewModel):TProperty}): IValidationContext&lt;TProperty&gt; }; \tgetValidationContextForCollection: { &lt;TProperty&gt;(propertyExpression: {(model: TViewModel):TProperty[]}): {(index: number): IValidationContext&lt;TProperty&gt;} } } <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u043e\u043d \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d. \u041e\u0446\u0435\u043d\u0438\u043c \u044d\u0442\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435. \u0412\u043e\u0442, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0443 \u043f\u043e\u043b\u044f \u00ab\u0418\u043c\u044f\u00bb:   <\/p>\n<pre><code class=\"javascript\">&lt;FormGroup \tlabel=&quot;\u0418\u043c\u044f&quot; \tvalidationMessage={this.state.validationContext.getValidationMessageFor(m =&gt; m.name) }&gt; \t&lt;Commons.Textbox \t\tvalue={this.state.model.name} \t\twidth=&quot;normal&quot; \t\tonChange={getPropertySetter( \t\t\tthis.state.model, \t\t\tthis._setModel, \t\t\tviewModel =&gt; viewModel.name) } \/&gt; &lt;\/FormGroup&gt; <\/code><\/pre>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 this.state.validationContext \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f IValidationContext&lt;CustomFieldKindValueBackendViewModel&gt;, \u0437\u0430 \u0441\u0447\u0451\u0442 \u0447\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u0438 \u0432\u044b\u0431\u043e\u0440\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043c\u043e\u0434\u0435\u043b\u0438. \u041f\u0440\u0438\u0447\u0435\u043c \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0430 \u0434\u0430\u0436\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0437\u043b\u043e\u043f\u043e\u043b\u0443\u0447\u043d\u0430\u044f getPropertyNameByPropertyProvider, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u0432\u044b\u0448\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u0443\u044e \u0432 getValidationMessageFor \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430\u0434 \u0442\u0435\u043a\u0443\u0449\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c validation summary \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u043a\u0440\u0430\u0442\u0446\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 validation summary \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435.<br \/>  \u0422\u0430\u043a \u043a\u0430\u043a \u0441\u0430\u043c\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043a\u0430\u043a-\u0442\u043e \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a \u044d\u0442\u0438\u043c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c \u043f\u0440\u0438\u0432\u0435\u043b\u0438. \u041a\u0430\u0436\u0434\u043e\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043a\u043b\u044e\u0447\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u043a\u043b\u044e\u0447\u0435\u0439. \u0412 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u044b \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, \u0430 \u0435\u0441\u043b\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u2014 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0435\u0439. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043b\u044e\u0447\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0443\u0442\u044c \u043e\u0442 \u043a\u043e\u0440\u043d\u044f \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043e \u0435\u0451 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438. \u042d\u0442\u043e\u0442 \u043f\u0443\u0442\u044c \u0432 \u0438\u0442\u043e\u0433\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u043c\u0435\u043d\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438, \u0430 \u0434\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438. \u0412\u0441\u0451, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u2014 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c, \u0438 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c, \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435 \u0442\u0430\u043a\u0438\u0435 \u043f\u0443\u0442\u0438 \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c validation summary.<br \/>  \u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u0432\u043e \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0441 \u043a\u043b\u044e\u0447\u043e\u043c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u044f \u00ab\u0418\u043c\u044f\u00bb \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435:  <\/p>\n<pre><code class=\"cs\">private void RegisterEndUserInput( \tISubmodelInputRegistrator&lt;CustomFieldKindValueViewModel&gt; registrator, \tCustomFieldKind customFieldKind) { \t\/\/ \u0435\u0449\u0451 \u043a\u043e\u0434  \tregistrator.RegisterEndUserInput( \t\tcustomFieldKind, \t\tcfk =&gt; cfk.Name, \t\tthis, \t\tm =&gt; m.Name);  \t\/\/ \u0435\u0449\u0451 \u043a\u043e\u0434 } <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c this \u2014 \u043a\u0430\u043a \u0440\u0430\u0437 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e Name, \u044f\u0432\u043b\u044f\u044e\u0449\u0435\u0435\u0441\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043f\u0430\u0434\u0451\u0442 \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e Name \u043e\u0431\u044a\u0435\u043a\u0442\u0430 CustomFieldKind customFieldKind. \u0418\u0437 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043a\u043b\u044e\u0447 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u0438 \u0441 \u043d\u0438\u043c \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u044c \u0434\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 Name \u0432\u043e \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438.<br \/>  \u0412\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0434\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 CustomFieldKind \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0438\u043c\u0435\u043d\u0438:  <\/p>\n<pre><code class=\"cs\">public void Validate(ValidationContext validationContext) { \t\/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438  \tvalidationContext \t\t.Validate(this, cfk =&gt; cfk.Name) \t\t.ToHave(() =&gt; !Name.IsNullOrEmpty()) \t\t.OrAddError&lt;CustomFieldCustomizationTemplateComponent&gt;(c =&gt; c.NameRequired);  \t\/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 } <\/code><\/pre>\n<p>  \u0412 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 \u0431\u0434 \u043c\u044b \u043f\u043e\u0439\u043c\u0451\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u0435\u043d \u0438 \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0451\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f, \u043a\u043b\u044e\u0447 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 CustomFieldKind.Name \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043c\u0435\u0447\u0435\u043d \u043a\u0430\u043a \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439, \u0438 \u0441 \u043d\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435.<\/p>\n<h2>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e, \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 UI. \u0412 \u043d\u0435\u0439 \u0435\u0441\u0442\u044c \u043a\u0430\u043a \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0435 \u043f\u043b\u044e\u0441\u044b \u0432 \u0432\u0438\u0434\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u0430\u043a \u0438 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0435 \u043c\u0438\u043d\u0443\u0441\u044b, \u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0443\u043c\u043e\u043b\u0447\u0430\u043b \ud83d\ude42<br \/>  \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0432\u043e-\u043f\u0435\u0440\u0432\u044b\u0445 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u0432\u0430\u0441 \u0437\u0430\u0434\u0443\u043c\u0430\u0442\u044c\u0441\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 UI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0441\u0443\u0440\u043e\u0432\u044b\u0439 Enterprise. \u041d\u0435 \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041d\u0430\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f ReactJS, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u0430\u043c \u043f\u043e\u0434\u043e\u0439\u0434\u0451\u0442 \u0447\u0442\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0435. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0434\u0441\u0442\u0435\u0433\u043d\u0451\u0442 \u0442\u0435\u0445, \u043a\u0442\u043e \u0443\u0432\u0438\u0434\u0435\u043b \u0432 \u043d\u0435\u0439 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f, \u043d\u0435 \u0441\u0442\u0435\u0441\u043d\u044f\u0442\u044c\u0441\u044f \u0438 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0448 \u043a\u043e\u0434 \u043b\u0443\u0447\u0448\u0435! \u041e\u0447\u0435\u043d\u044c \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u043a\u0440\u0438\u0442\u0438\u043a\u0443 \u0438 \u0441\u043e\u0432\u0435\u0442\u044b \u043e\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430.               <\/p>\n<div class=\"clear\"><\/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:\/\/habrahabr.ru\/post\/276235\/\"> https:\/\/habrahabr.ru\/post\/276235\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.<br \/>  \u041f\u0440\u043e\u0448\u043b\u043e \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0433\u043e\u0434\u0430 \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u0430\u043a \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c ReactJS \u0432 \u043d\u0430\u0448\u0435\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u0438 \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0441\u043e\u0437\u0440\u0435\u043b\u0438 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u043c, \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u0435\u0435 \u0441\u0442\u0430\u043b\u0430 \u043d\u0430\u0448\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0441\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0432\u0435\u043b\u0438 \u043d\u0430\u0441 \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0435\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c.<br \/>  \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438. \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0438 \u044f \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u043a\u0430\u043a \u0435\u0441\u0442\u044c. \u0412\u0441\u0435 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u044b \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0438 \u044f \u0437\u0430\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044e \u0432 \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043a \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0443\u0434\u043e\u0431\u043d\u0435\u0435<\/p>\n<h2>\u0410 \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430\u0447\u0435\u043c \u0432\u0441\u0451 \u044d\u0442\u043e<\/h2>\n<p>  \u041c\u044b \u2014 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f, \u043d\u0430\u0448 \u0448\u0442\u0430\u0442 \u2014 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 50 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, 20 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438. \u0421\u0435\u0439\u0447\u0430\u0441 \u0443 \u043d\u0430\u0441 4 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043f\u043e 5 fullstack \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u041d\u043e \u043e\u0434\u043d\u043e \u0434\u0435\u043b\u043e \u2014 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0435\u0431\u044f fullstack-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c, \u0430 \u0434\u0440\u0443\u0433\u043e\u0435 \u0434\u0435\u043b\u043e \u2014 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e <u>\u0445\u043e\u0440\u043e\u0448\u043e<\/u> \u0432 \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u044f\u0445 \u0440\u0430\u0431\u043e\u0442\u044b SQL Server&#8217;\u0430, ASP.NET, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 C#, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0432 OOP, DDD, \u0437\u043d\u0430\u0442\u044c HTML, CSS, JS \u0438 \u0443\u043c\u0435\u0442\u044c \u044d\u0442\u0438\u043c \u0432\u0441\u0435\u043c \u0440\u0430\u0437\u0443\u043c\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0442\u044f\u0433\u043e\u0442\u0435\u0435\u0442 \u043a \u0447\u0435\u043c\u0443-\u0442\u043e \u0441\u0432\u043e\u0435\u043c\u0443, \u043d\u043e \u0432\u0441\u0435 \u043c\u044b \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 .NET \u0438 90% \u043a\u043e\u0434\u0430 \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u043d\u0430 C#.<br \/>  \u041d\u0430\u0448 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u2014 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u0430 \u2014 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0438 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0439 \u0441\u0430\u043c\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u043f\u043e\u0434 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0430\u0439\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u044b \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438, \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u042d\u0442\u043e\u0442 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0430\u0439\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e UI&#8217;\u0430, \u0438 \u0447\u0435\u043c \u0441\u0438\u043b\u044c\u043d\u0435\u0435 \u043c\u044b \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0435\u043c\u0441\u044f, \u0447\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u043d\u043a\u0438\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043c\u044b \u0434\u0430\u0451\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c, \u0447\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0444\u0438\u0447 \u043c\u044b \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c \u043e\u043d \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u044b\u0442\u044c \u0433\u043e\u043b\u043e\u0441\u043b\u043e\u0432\u043d\u044b\u043c, \u043f\u0430\u0440\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u043e\u0432 (\u0443\u0436\u0435 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c, \u0438 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u043e\u0432 \u0442\u0430\u043c \u043e\u0442\u043d\u044e\u0434\u044c \u043d\u0435 \u043f\u0430\u0440\u0430!):  <\/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-279496","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/279496","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=279496"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/279496\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=279496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=279496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=279496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}