{"id":316324,"date":"2021-01-13T15:01:34","date_gmt":"2021-01-13T15:01:34","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=316324"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=316324","title":{"rendered":"\u041f\u0430\u043a\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 mobx form validation kit 2.0 (TypeScript \/ Flutter)"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<h2>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>  \u041f\u043e\u0447\u0442\u0438 \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043f\u0435\u0440\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 &quot;<a href=\"https:\/\/habr.com\/ru\/post\/470537\/\">\u041d\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u0434\u043b\u044f React \u043d\u0430 Mobx @quantumart\/mobx-form-validation-kit<\/a>&quot;<br \/>  \u0412\u0440\u0435\u043c\u044f \u0448\u043b\u043e, \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0438 \u043d\u0435 \u0441\u0442\u043e\u044f\u043b\u0430 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435, \u0434\u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043a\u0430\u043a \u0438 \u043d\u0430\u0448\u0435 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435 \u0432 \u0446\u0435\u043b\u043e\u043c. \u041c\u044b \u043f\u0435\u0440\u0435\u0448\u043b\u0438 \u043d\u0430 flutter, \u043f\u043e \u043f\u0443\u0442\u0438 \u043f\u043e\u043f\u0438\u043d\u0430\u0432 ReactNative, \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0418 \u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u0438 \u043e\u0442 \u043d\u0430\u0441 \u043d\u043e\u0432\u044b\u0445 \u0438 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043f\u0435\u0440\u0435\u0440\u0430\u0431\u043e\u0442\u043a\u0438 mobx-form-validation-kit.<br \/>  \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0440\u0430\u0434 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u043c \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u0430\u043a\u0435\u0442\u0430 mobx-form-validation-kit.<br \/>  \u0414\u043b\u044f \u0441\u0442\u0440\u043e\u0433\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e TypeScript<br \/>  <a href=\"https:\/\/www.npmjs.com\/package\/@quantumart\/mobx-form-validation-kit\" rel=\"nofollow\">mobx-form-validation-kit 2.0<\/a><br \/>  \u0418 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043f\u043e\u0434 Flutter<br \/>  <a href=\"https:\/\/pub.dev\/packages\/flutter_mobx_form_validation_kit\" rel=\"nofollow\"> flutter_mobx_form_validation_kit 2.0<\/a><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/sg\/cx\/qb\/sgcxqbdh_qdnifgudrwwnuhdvrq.png\"><br \/>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0434\u043b\u044f TypeScript \u0438 Flutter, \u0447\u0438\u0442\u0430\u0442\u044c \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u0432\u0435\u0440\u0441\u0438\u044e [\u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u0434\u0430], \u0430 \u044d\u043d\u0442\u0443\u0437\u0438\u0430\u0441\u0442\u044b \u043e\u0431\u043e\u0438\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u0441\u043c\u043e\u0433\u0443\u0442 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0434\u0438\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432\u0435\u0437\u0434\u0435.<\/p>\n<h2>Get Started.<\/h2>\n<p>  \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u0430\u0445 \u043a \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043a\u043e\u0434\u0430, \u043d\u043e \u044f \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 MVC (Model-View-Controller).  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b><br \/>  \u0422.\u0435. \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u00ab\u0433\u043b\u0443\u043f\u044b\u0435\u00bb \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0430 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0430 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f) \u0437\u0430\u0448\u0438\u0442\u0430 \u0432 Store-\u0430\u0445.<br \/>  \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u0442\u0440\u043e\u0438\u0442\u044c\u0441\u044f \u043d\u0430 react-\u0445\u0443\u043a\u0430\u0445, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435, \u0447\u0442\u043e \u043e\u043d \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439, \u043d\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043f\u0440\u0438 \u00ab\u043a\u043b\u0430\u0441\u0441\u043e\u0432\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435\u00bb.  <\/p>\n<hr>\n<p>  <b>Flutter<\/b><br \/>  \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e MVC \u043f\u043e\u0434\u0445\u043e\u0434 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e widget-\u044b \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043e\u0442 StatelessWidget \u043a\u043b\u0430\u0441\u0441\u0430, \u043d\u0430\u0448\u0438 widget-\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430\u043c\u0438 StatefulWidget. \u042d\u0442\u043e \u0434\u043e\u043f\u0443\u0449\u0435\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439 \u043f\u0430\u043a\u0435\u0442\u0430 <a href=\"https:\/\/pub.dev\/packages\/flutter_mobx\" rel=\"nofollow\">flutter_mobx<\/a> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 widget-\u0430\u0445 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 state management-\u0430 mobx. \u041d\u043e \u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u0432 \u043d\u0430\u0448\u0438\u0445 StatefulWidget-\u0430\u0445 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438.<br \/>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437, \u044f \u0441\u0442\u0430\u0442\u044c\u044e \u043d\u0430\u0447\u043d\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0441 \u0441\u043e\u0432\u0441\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432. \u0410 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430.  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b><br \/>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442<br \/>  <i>npx create-react-app my-app &#8212;template typescript<\/i><\/p>\n<p>  \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c mobx<br \/>  mobx: &quot;^5.15.7&quot;,<br \/>  mobx-react-lite: &quot;^2.2.2&quot;,<br \/>  \u0422\u0443\u0442 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u043c\u0430\u0440\u043a\u0443, \u0447\u0442\u043e \u0432 \u043d\u043e\u0432\u043e\u0439 6-\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 mobx, \u0440\u0435\u0431\u044f\u0442\u0430 \u0443\u0448\u043b\u0438 \u043e\u0442 \u0434\u0435\u043a\u0430\u0440\u0430\u0442\u043e\u0440\u043e\u0432\u2026 \u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u043d\u0430 6-\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u00abmobx-form-validation-kit\u00bb \u043f\u043e\u043a\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430. \u042f \u0434\u0443\u043c\u0430\u044e \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u043b\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e \u00abmobx-form-validation-kit 3.0\u00bb \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 mobx 6+. \u041d\u043e API \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u0442\u043e \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430.<br \/>  \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 mobx-form-validation-kit<br \/>  <i>npm install @quantumart\/mobx-form-validation-kit<\/i><\/p>\n<p>  \u0412 \u0444\u0430\u0439\u043b tsconfig.json \u0435\u0449\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c.<br \/>  \u00abexperimentalDecorators\u00bb: true,  <\/p>\n<hr>\n<p>  <b>Flutter<\/b><br \/>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442<br \/>  <i>flutter create myapp<\/i><\/p>\n<p>  \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445 (pubspec.yaml) \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435.<br \/>  <i>dependencies:<br \/>   flutter:<br \/>   sdk: flutter<br \/>   flutter_mobx: ^1.1.0+2<br \/>   flutter_mobx_form_validation_kit:: ^2.0.0<\/i><\/p>\n<p>  <i>dev_dependencies:<br \/>   flutter_test:<br \/>   sdk: flutter<br \/>   build_runner: ^1.10.11<br \/>   mobx_codegen: ^1.1.2<\/i><br \/>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u0412 \u0446\u0435\u043b\u043e\u043c, \u044f \u0431\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u043e\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 mobx \u0438\u043b\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0430\u043f\u043e\u043a. \u0418\u0431\u043e \u044d\u0442\u043e \u0442\u0435\u043c\u0430 \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438. \u042f \u0438\u0441\u0445\u043e\u0436\u0443 \u0438\u0437 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e, \u0440\u0430\u0437 \u0432\u044b \u0447\u0438\u0442\u0430\u0435\u0442\u0435 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e, \u0442\u043e \u0443\u0436\u0435 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0438c\u044c \u0441 mobx \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442\u0435, \u043e \u0447\u0435\u043c \u0438\u0434\u0435\u0442 \u0440\u0435\u0447\u044c \u0438 \u043a\u0430\u043a\u0438\u0435 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0430 \u0444\u043e\u0440\u043c\u0430\u0445 \u0432\u0432\u043e\u0434\u0430.<br \/>  \u0414\u0435\u043b\u0430\u0442\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0444\u043e\u0440\u043c\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438.  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b><br \/>  App \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442  <\/p>\n<pre><code class=\"javascript\">function App() {   return (     &lt;RegistrationComponent \/&gt;   ); } <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 Store\u2026 \u041f\u043e\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0445 \u0434\u0432\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u0438\u043a\u0430.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/mk\/w1\/ds\/mkw1dscdna7-zpp0unxxits4qbm.png\">  <\/p>\n<hr>\n<p>  <b>Flutter<\/b><br \/>  Main \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442  <\/p>\n<pre><code class=\"dart\">class MyApp extends StatelessWidget {   \/\/ This widget is the root of your application.   @override   Widget build(BuildContext context) {     return MaterialApp(       title: 'Flutter Demo',       theme: ThemeData(         primarySwatch: Colors.blue,         visualDensity: VisualDensity.adaptivePlatformDensity,       ),       home: Scaffold(body: SafeArea(child: Registration())),     );   } } <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 Store\u2026 \u041f\u043e\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0445 \u0434\u0432\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u0438\u043a\u0430.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/8p\/pz\/pv\/8ppzpvwlytfsdb-yzvl_uyl_ooa.png\"><br \/>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u0417\u0430\u043a\u043e\u043d\u0447\u0438\u0432 \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0447\u0430\u044f \u0444\u043e\u0440\u043c\u043e\u0447\u043a\u0430\/\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0430 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438 \u0432\u0432\u043e\u0434\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043f\u043e\u043b\u0435 \u0432\u0432\u043e\u0434\u0430 (input \/ TextField) \u0441\u0432\u0435\u0440\u0445\u0443 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<br \/>  \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e. <br \/>  \u041c\u044b \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043c \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0418\u043c\u044f \u043f\u0443\u0441\u0442\u044b\u043c.  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b><br \/>  \u0418\u0437\u043c\u0435\u043d\u0438\u043c \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 FormRegistration \u043e\u0442 ControlsCollection. \u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \/ \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c.  <\/p>\n<pre><code class=\"javascript\">interface FormRegistration extends ControlsCollection {   name: FormControl&lt;string&gt;; }<\/code><\/pre>\n<p>  \u0421\u0430\u043c Store \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c observable \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u043d\u0438 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u044b. \u0412\u0441\u044f \u00ab\u043c\u0430\u0433\u0438\u044f\u00bb \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.  <\/p>\n<pre><code class=\"javascript\">export class RegistrationStore {   public form: FormGroup&lt;FormRegistration&gt;;    constructor() {     this.form = new FormGroup&lt;FormRegistration&gt;({       name: new FormControl&lt;string&gt;(&quot;&quot;, {         validators: [requiredValidator()],       }),     });   } }<\/code><\/pre>\n<p>  \u041d\u0430\u0448 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:  <\/p>\n<pre><code class=\"javascript\">const store = new RegistrationStore(); export function RegistrationComponent() {   return useObserver(() =&gt; (     &lt;div&gt;       &lt;p&gt;{store.form.controls.name.value}&lt;\/p&gt;       &lt;input         type=&quot;text&quot;         value={store.form.controls.name.value}         onChange={(event: React.ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {           store.form.controls.name.value = event.target.value;         }}       \/&gt;     &lt;\/div&gt;   )); }<\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. \u041b\u0438\u0448\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0438\u0437 store.form.controls.name.value.<br \/>  \u0412 \u0446\u0435\u043b\u043e\u043c \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e \u0431\u044b \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432 FormControl \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438.<br \/>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0438 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u043d\u0438\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043c\u0438 \u043f\u043e\u043b\u044f \u0432\u0432\u043e\u0434\u0430:  <\/p>\n<pre><code class=\"javascript\"> \u2026 {store.form.controls.name.errors.map((error) =&gt; (         &lt;p style={{ color: &quot;#FFF&quot; }}&gt;{error.message}&lt;\/p&gt;       ))} \u2026 <\/code><\/pre>\n<p>  <\/p>\n<hr>\n<p>  <b>Flutter<\/b><br \/>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0442 ControlsCollection. \u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0438 \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \/ \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c.  <\/p>\n<pre><code class=\"dart\">class RegistrationForm extends ControlsCollection {   final FormControl&lt;String&gt; name;   RegistrationForm({this.name});   @override   Iterable&lt;AbstractControl&gt; allFields() =&gt; [this.name]; }<\/code><\/pre>\n<p>  \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 Flutter \u044d\u0442\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 reflection \u0438\u043b\u0438 mirror. \u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 override-\u0434\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 allFields \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0440\u043d\u0435\u0442 \u0432\u0435\u0441\u044c \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u043b\u0435\u0439 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435.<\/p>\n<p>  \u0414\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e store \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u0442\u0430\u043a. \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0434\u0430\u0436\u0435 mobx \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u0434\u043b\u044f store \u043d\u0435 \u043d\u0443\u0436\u043d\u0430. \u0412\u0441\u044f \u00ab\u043c\u0430\u0433\u0438\u044f\u00bb \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.  <\/p>\n<pre><code class=\"dart\">class RegistrationStore {   FormGroup&lt;RegistrationForm&gt; form;    RegistrationStore() {     this.form = FormGroup(RegistrationForm(         name: FormControl(             value: &quot;&quot;,             options: OptionsFormControl(validators: [requiredValidator()]))));   }    void dispose() {     this.form.dispose();   } }<\/code><\/pre>\n<p>  \u0421\u0430\u043c \u0436\u0435 \u0432\u0438\u0434\u0436\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a.  <\/p>\n<pre><code class=\"dart\">class _RegistrationState extends State&lt;Registration&gt; {   RegistrationStore store = RegistrationStore();    @override   void dispose() {     store.dispose();     super.dispose();   }    @override   Widget build(_) =&gt; Observer(builder: (BuildContext context) {         return Column(             crossAxisAlignment: CrossAxisAlignment.start,             mainAxisAlignment: MainAxisAlignment.center,             children: [               Text(store.form.controls.name.value,                   style: TextStyle(fontSize: 20)),               TextField(                 controller: store.form.controls.name.controller,                 onChanged: (String text) =&gt;                     store.form.controls.name.value = text,                 decoration: InputDecoration(                   border: OutlineInputBorder(),                   labelText: &quot;\u0418\u043c\u044f&quot;,                 ),               ),             ]);       }); } <\/code><\/pre>\n<p>  \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 dispose. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u0418 \u043e\u0442 \u043d\u0438\u0445 \u043d\u0443\u0436\u043d\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0435\u0441\u043b\u0438 \u0444\u043e\u0440\u043c\u0430 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0443\u0436\u043d\u043e\u0439.<br \/>  \u0421\u0430\u043c\u043e \u0436\u0435 \u043f\u043e\u043b\u0435 \u0432\u0432\u043e\u0434\u0430 TextField \u0441\u0442\u0430\u043b\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a.<br \/>  <i>TextField(<br \/>   controller: store.form.controls.name.controller,<br \/>   onChanged: (String text) =&gt;<br \/>   store.form.controls.name.value = text,<br \/>   decoration: InputDecoration(<br \/>   border: OutlineInputBorder(),<br \/>   labelText: \u00ab\u0418\u043c\u044f\u00bb,<br \/>   ),<\/i><br \/>  \u041f\u0440\u043e\u0448\u0443 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0438 TextFormField, \u043d\u0438 \u043e\u0431\u0435\u0440\u0442\u043e\u0447\u043d\u044b\u0439 Form \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u0430\u043c \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0439 TextField.<br \/>  TextField-\u0443 \u043c\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 controller:<br \/>  <i>controller: store.form.controls.name.controller<\/i><br \/>  \u041a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0432 Store.<br \/>  \u0418 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0430\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f onChanged:<br \/>  <i>onChanged: (String text) =&gt; store.form.controls.name.value = text<\/i><br \/>  \u0412 \u0446\u0435\u043b\u043e\u043c \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e \u0431\u044b \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432 FormControl \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438.<br \/>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0438 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u043d\u0438\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043c\u0438 \u043f\u043e\u043b\u044f \u0432\u0432\u043e\u0434\u0430:  <\/p>\n<pre><code class=\"dart\"> \u2026 ...store.form.controls.name.errors.map((error) =&gt; Text(                   error.message,                   style: TextStyle(color: Colors.red, fontSize: 15))) \u2026 <\/code><\/pre>\n<p>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u0418\u0442\u043e\u0433\u043e\u043c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0430\u043a\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/sg\/cx\/qb\/sgcxqbdh_qdnifgudrwwnuhdvrq.png\"><\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u0432\u043e\u0434\u0438\u0442\u044c, \u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 \u0442\u0443\u0442 \u0436\u0435 \u043f\u0440\u043e\u043f\u0430\u0434\u0435\u0442.<br \/>  \u041d\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0439 \u043d\u0430\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0441\u0430\u043c\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u0432\u043e\u0434\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0438\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0444\u043e\u043a\u0443\u0441 \u0443 \u043f\u043e\u043b\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0442\u0435\u0440\u044f\u043d. mobx-form-validation-kit \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432\u0435\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e.<br \/>  \u2022 <b>pristine<\/b>: boolean \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 FormControl, \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c.<br \/>  \u2022 <b>dirty<\/b>: boolean \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 FormControl, \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c.<br \/>  \u2022 <b>untouched<\/b>: boolean \u2014 \u0434\u043b\u044f FormControl \u2013 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0414\u043b\u044f FormGroup \u0438 FormArray \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 FormControl-\u043e\u0432 \u043d\u0435 \u0431\u044b\u043b \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 false \u0432 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0444\u043e\u043a\u0443\u0441 \u0431\u044b\u043b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u043b \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d, \u043d\u043e \u0438 \u0441\u043d\u044f\u0442 \u0441 \u043f\u043e\u043b\u044f.<br \/>  \u2022 <b>touched<\/b>: boolean \u2014 \u0414\u043b\u044f FormControl \u2013 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 \u0431\u044b\u043b\u043e \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0414\u043b\u044f FormGroup \u0438 FormArray \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 FormControl-\u043e\u0432 \u0431\u044b\u043b \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 true \u0432 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0444\u043e\u043a\u0443\u0441 \u0431\u044b\u043b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u043b \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d, \u043d\u043e \u0438 \u0441\u043d\u044f\u0442 \u0441 \u043f\u043e\u043b\u044f.<br \/>  \u2022 <b>focused<\/b>: boolean \u2014 \u0434\u043b\u044f FormControl \u2013 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 \u0441\u0435\u0439\u0447\u0430\u0441 \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0414\u043b\u044f FormGroup \u0438 FormArray \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 FormControl-\u043e\u0432 \u0441\u0435\u0439\u0447\u0430\u0441 \u0432 \u0444\u043e\u043a\u0443\u0441\u0435.<br \/>  \u041d\u043e \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c FormControl \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u043b\u044f.  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b>  <\/p>\n<pre><code class=\"javascript\"> \u2026 &lt;input         type=&quot;text&quot;         value={store.form.controls.name.value}         ref={(elment) =&gt; (props.control.element = elment)}         onChange={(event: React.ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {           store.form.controls.name.value = event.target.value;         }}         onBlur={(event: React.FocusEvent&lt;HTMLInputElement&gt;) =&gt; {           store.form.controls.name.setTouched(true);           store.form.controls.name.setFocused(false);         }}         onFocus={(event: React.FocusEvent&lt;HTMLInputElement&gt;) =&gt; {           store.form.controls.name.setFocused(true);         }}       \/&gt;       {store.form.controls.name.touched &amp;&amp;         store.form.controls.name.errors.map((error) =&gt; (           &lt;p style={{ color: &quot;#F00&quot; }}&gt;{error.message}&lt;\/p&gt;         ))} \u2026 <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u043c\u0435\u0442\u043e\u0434\u044b<br \/>  \u2022 onChange <br \/>  \u2022 onBlur<br \/>  \u2022 onFocus<br \/>  \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u0432\u043f\u043e\u043b\u043d\u0435 \u0441\u0435\u0431\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434. \u0414\u0430\u0431\u044b \u0438\u0445 \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e \u0441\u0442\u043e \u0440\u0430\u0437, \u0432 \u043c\u0438\u043d\u0438-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e InputFormControl \u0438\u043b\u0438 TextAreaFormControl.<br \/>  \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a.  <\/p>\n<pre><code class=\"javascript\">&lt;input         type=&quot;text&quot;         value={store.form.controls.name.value}         {...InputFormControl.bindActions(store.form.controls.name)}       \/&gt;<\/code><\/pre>\n<p>  \u041d\u043e \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0439, \u0438 \u043e\u043d \u0434\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.   <\/p>\n<hr>\n<p>  <b>Flutter<\/b><br \/>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430, \u0442.\u043a. \u043a\u043b\u0438\u043a \u0432 \u043f\u0443\u0441\u0442\u043e\u044e \u0437\u043e\u043d\u0443 \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u043e flutter \u043f\u043e\u0442\u0435\u0440\u0435\u0439 \u0444\u043e\u043a\u0443\u0441\u0430, \u043c\u044b \u043e\u0431\u0435\u0440\u043d\u0435\u043c \u0432\u0435\u0441\u044c \u043d\u0430\u0448 Column \u0432 InkWell.  <\/p>\n<pre><code class=\"dart\"> return InkWell(             onTap: () =&gt; FocusScope.of(context).unfocus(),             child: Column(\u2026)); <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 FocusNode \u0432 Widget   <\/p>\n<pre><code class=\"dart\"> \u2026     _focusNode = FocusNode();     _focusNode.addListener(() {   if (!_focusNode.hasFocus) {         store.form.controls.name.setTouched(true);       }       store.form.controls.name.setFocused(_focusNode.hasFocus);    });  \u2026 <\/code><\/pre>\n<p>  \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0439 \u043a\u043e\u0434 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0433\u043b\u0443\u043f\u043e \u0438 \u0441\u043a\u0443\u0447\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 FormControl \u0443\u0436\u0435 \u0432\u0448\u0438\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 focusNode.<br \/>  \u0418\u0442\u043e\u0433\u043e \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0438\u043c  <\/p>\n<pre><code class=\"dart\"> \u2026 TextField(                       focusNode: store.form.controls.name.focusNode,                       controller: store.form.controls.name.controller,                       onChanged: (String text) =&gt;                           store.form.controls.name.value = text,                       decoration: InputDecoration(                         border: OutlineInputBorder(),                         labelText: &quot;\u0418\u043c\u044f&quot;,                       )),                   if (store.form.controls.name.touched)                     ...store.form.controls.name.errors.map((error) =&gt; Text(                         error.message,                         style: TextStyle(color: Colors.red, fontSize: 15))) \u2026 <\/code><\/pre>\n<p>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043f\u043e\u043b\u0435 \u00ab\u043f\u043e\u0442\u0440\u043e\u0433\u0430\u043b\u0438\u00bb (\u0442.\u0435. \u043e\u043d\u043e \u043f\u043e\u0442\u0435\u0440\u044f\u043b\u043e \u0444\u043e\u043a\u0443\u0441 \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437).<br \/>  \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443, \u0447\u0442\u043e \u0443\u0436 \u0431\u043e\u043b\u044c\u043d\u043e \u0447\u0430\u0441\u0442\u043e \u043f\u0438\u0448\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 <i>store.form.controls.name<\/i>.<br \/>  \u0418 \u043b\u044e\u0431\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0431\u0435\u0440\u0442\u043a\u0438 \u043d\u0430\u0434 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c \u0432\u0432\u043e\u0434\u0430, \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438\u2026 \u041d\u043e\u2026 \u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u043e \u0433\u0440\u0443\u0441\u0442\u043d\u043e\u043c)<br \/>  \u0412 \u0438\u0442\u043e\u0433\u0435, \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u043d\u0430\u0448\u0435 \u043f\u043e\u043b\u0435 \u0432\u0432\u043e\u0434\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.<br \/>  \u0418 \u043d\u0430\u0447\u043d\u0435\u043c \u0440\u0430\u0437\u0431\u043e\u0440 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439.  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b><br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/zd\/x2\/i_\/zdx2i_wodiptpcdab3at81h57ag.png\">  <\/p>\n<hr>\n<p>  <b>Flutter<\/b><br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/t7\/nd\/2u\/t7nd2u5ahdcyppfy0kv0fkqwlri.png\"><br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/kt\/fx\/mx\/ktfxmxia87pscbut39blng55peq.png\"><br \/>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043b\u043e\u0436\u043d\u044b \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u0441 \u043a\u043e\u0434\u043e\u043c \u043c\u044b \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u043b\u0438.<br \/>  \u0425\u043e\u0442\u044f \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e string, \u043d\u043e FormControl \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043b\u044e\u0431\u044b\u043c \u0442\u0438\u043f\u043e\u043c \u0432 \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u0430\u0448\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435.<\/p>\n<h2>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430<\/h2>\n<p>  \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0433\u043b\u0430\u0432\u0435 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0443 \u0447\u0430\u0441\u0442\u044c FormControl-\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0442\u0430\u043a \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043b \u0432 \u0441\u0432\u043e\u0435\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 &quot;<a href=\"https:\/\/habr.com\/ru\/post\/470537\/\">\u041d\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u0434\u043b\u044f React \u043d\u0430 Mobx @quantumart\/mobx-form-validation-kit<\/a><br \/>  \u042f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a \u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u043e\u043d\u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442.<br \/>  \u0414\u0430\u043b\u0435\u0435 \u044f \u043f\u043e\u0432\u0435\u0434\u0430\u044e \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435.<br \/>  \u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 \u0438 \u0438\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438.<br \/>  \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 mobx-form-validation-kit \u0438\u043c\u0435\u0435\u0442 \u0442\u0440\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 \u0443\u0437\u043b\u043e\u0432:<br \/>  \u2022 <b>FormGroup<\/b> \u2013 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u0435. \u041a\u043b\u0430\u0441\u0441 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439, \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 generic \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u043f\u043e\u043b\u0435\u0439. <br \/>  \u2022 <b>FormControl<\/b> \u2013 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u041a\u043b\u0430\u0441\u0441 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439, \u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 generic \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u0438\u043f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0445\u0440\u0430\u043d\u0438\u0442\u044c.<br \/>  \u2022 <b>FormArray<\/b> \u2013 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  \u0421\u0430\u043c\u0438 \u0443\u0437\u043b\u044b \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0432 \u0434\u0440\u0435\u0432\u043e\u0432\u0438\u0434\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043b\u044e\u0431\u043e\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u0441\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 FormGroup.<br \/>  FormGroup<br \/>   \u2014 FormControl<br \/>   \u2014 FormControl<br \/>   \u2014  \u2014 FormGroup<br \/>   \u2014  \u2014 FormArray<br \/>   \u2014  \u2014  \u2014 FormGroup<br \/>   \u2014  \u2014  \u2014  \u2014 FormControl<br \/>   \u2014  \u2014 FormArray<br \/>   \u2014  \u2014  \u2014 FormControl<\/p>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u043e\u043f\u0446\u0438\u0439 \u043f\u0440\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438:<br \/>  \u2022 <b>validators<\/b>: ValidatorsFunction[] \u2013 \u043d\u0430\u0431\u043e\u0440 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432.<br \/>  \u2022 <b>activate<\/b>: (() =&gt; boolean) | null \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c\/\u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u0432\u0441\u0435\u0433\u0434\u0430). \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u0442\u044b \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0443\u0441\u043b\u0443\u0433\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0433\u0430\u043b\u043e\u0447\u043a\u0430 \u00ab\u0411\u0435\u0437\u043b\u0438\u043c\u0438\u0442\u043d\u044b\u0439\u00bb. \u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043f\u0438\u0441\u0430\u0432 \u0441\u044e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 observable \u043f\u043e\u043b\u044f \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0433\u043e \u0437\u0430 \u0447\u0435\u043a\u0431\u043e\u043a\u0441 \u00ab\u0411\u0435\u0437\u043b\u0438\u043c\u0438\u0442\u043d\u044b\u0439\u00bb, \u043c\u043e\u0436\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u043a \u043f\u043e\u043b\u044e \u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0434\u0430\u0442\u044b, \u0430 \u043d\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u043a\u0430\u0436\u0434\u0443\u044e \u0438\u0437 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u043f\u043e\u043b\u044f \u0434\u0430\u0442\u0430.<br \/>  \u2022 <b>additionalData<\/b>: any \/ dynamic \u2014 \u0431\u043b\u043e\u043a \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 FormControl \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u042d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0431\u0438\u043b\u0434\u0435\u0440\u044b \u0434\u043b\u044f FormControl \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0445\u0430\u0440\u043a\u043e\u0434\u0438\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0430 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0441\u0432\u044f\u0437\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044b \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0425\u043e\u0442\u044f \u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0438 \u043d\u0435\u043e\u0441\u043f\u043e\u0440\u0438\u043c\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u043b\u044f additionalData \u043c\u044b \u0442\u0430\u043a \u0438 \u043d\u0435 \u0441\u043c\u043e\u0433\u043b\u0438 \u043d\u0430\u0439\u0442\u0438, \u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u0438\u043c\u0435\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c, \u0447\u0435\u043c \u0441\u0442\u0440\u0430\u0434\u0430\u0442\u044c \u0431\u0435\u0437 \u043d\u0435\u0435.<br \/>  \u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043b\u044f FormControl \u0435\u0441\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043e\u043f\u0446\u0438\u0439:<br \/>  \u2022 <b>onChangeValue<\/b>: UpdateValidValueHandler | null \u2014 \u0421\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<br \/>  \u2022 <b>onChangeValidValue<\/b>: UpdateValidValueHandler | null \u2014 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<br \/>  \u2022 <b>callSetterOnInitialize<\/b>: boolean \u2014 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c `onChangeValidValue` \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 `FormControl`.<br \/>  \u2022 <b>callSetterOnReinitialize<\/b>: boolean \u2014 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c `onChangeValidValue` \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0433\u0435\u0442\u0442\u0435\u0440\u0430 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.<\/p>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u0435\u0440\u0435\u0432\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u043b\u0435\u0439<br \/>  \u2022 <b>processing<\/b>: boolean \u2014 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430. mobx-form-validation-kit \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0435, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u043f\u043e \u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044e.<br \/>  \u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 wait, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435\u00bb \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e.  <\/p>\n<pre><code class=\"javascript\"> await this.form.wait(); if (this.form.invalid) { \u2026<\/code><\/pre>\n<p>  \u2022 <b>disabled<\/b>: boolean \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0430 (\u043a\u043e\u043d\u0442\u0440\u043e\u043b \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u0430\u043b\u0438\u0434\u0435\u043d)<br \/>  \u2022 <b>active<\/b>: boolean \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430. \u0417\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438. \u0414\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u043a\u0440\u044b\u0442\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u043e\u043b\u0435\u0439 \u043d\u0430 \u0444\u043e\u0440\u043c\u0435 \u0438 \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438.<br \/>  \u2022 <b>invalid<\/b>: boolean \u2014 \u0434\u043b\u044f FormControl \u2013 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438. \u0414\u043b\u044f FormGroup \u0438 FormArray \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u043b\u0438\u0431\u043e \u0441\u0430\u043c \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0438, \u043b\u0438\u0431\u043e \u043e\u0434\u043d\u043e \u0438\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 (\u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0437 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438) \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438. \u0422.\u0435. \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 \u0432\u0441\u0435\u0439 \u0444\u043e\u0440\u043c\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043e\u0434\u043d\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 invalid \u0438\u043b\u0438 valid \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e FormGroup.<br \/>  \u2022 <b>valid<\/b>: boolean \u2014 \u0434\u043b\u044f FormControl \u2013 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438. \u0414\u043b\u044f FormGroup \u0438 FormArray \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u043b\u0438\u0431\u043e \u0441\u0430\u043c \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0438, \u0438 \u043d\u0438 \u043e\u0434\u043d\u043e \u0438\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 (\u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0437 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438) \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438.<br \/>  \u2022 <b>pristine<\/b>: boolean \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043f\u043e\u043b\u0435, \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c.<br \/>  \u2022 <b>dirty<\/b>: boolean \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043f\u043e\u043b\u0435, \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c.<br \/>  \u2022 <b>untouched<\/b>: boolean \u2014 \u0434\u043b\u044f FormControl \u2013 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 input) \u043d\u0435 \u0431\u044b\u043b\u043e \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0414\u043b\u044f FormGroup \u0438 FormArray \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0438 \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 FormControl-\u043e\u0432 \u043d\u0435 \u0431\u044b\u043b \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 false \u0432 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0444\u043e\u043a\u0443\u0441 \u0431\u044b\u043b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u043b \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d, \u043d\u043e \u0438 \u0441\u043d\u044f\u0442 \u0441 \u043f\u043e\u043b\u044f.<br \/>  \u2022 <b>touched<\/b>: boolean \u2014 \u0414\u043b\u044f FormControl \u2013 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 input) \u0431\u044b\u043b\u043e \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0414\u043b\u044f FormGroup \u0438 FormArray \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 FormControl-\u043e\u0432 \u0431\u044b\u043b \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 true \u0432 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0444\u043e\u043a\u0443\u0441 \u0431\u044b\u043b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u043b \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d, \u043d\u043e \u0438 \u0441\u043d\u044f\u0442 \u0441 \u043f\u043e\u043b\u044f.<br \/>  \u2022 <b>focused<\/b>: boolean \u2014 \u0434\u043b\u044f FormControl \u2013 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 input) \u0441\u0435\u0439\u0447\u0430\u0441 \u0432 \u0444\u043e\u043a\u0443\u0441\u0435. \u0414\u043b\u044f FormGroup \u0438 FormArray \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 FormControl-\u043e\u0432 \u0441\u0435\u0439\u0447\u0430\u0441 \u0432 \u0444\u043e\u043a\u0443\u0441\u0435.<br \/>  \u2022 <b>errors<\/b>: ValidationEvent[] \u2014 \u043f\u043e\u043b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439, \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u043b\u0438\u0431\u043e FormControl, \u043b\u0438\u0431\u043e FormGroup, \u043b\u0438\u0431\u043e FormArray, \u0442.\u0435. \u043e\u0448\u0438\u0431\u043a\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430, \u0430 \u043d\u0435 \u0432\u0441\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435. \u0412\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043f\u043e\u043b\u0435 valid \/ invalid<br \/>  \u2022 <b>warnings<\/b>: ValidationEvent[] \u2014 \u043f\u043e\u043b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u00ab\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u00bb. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439, \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u043b\u0438\u0431\u043e FormControl, \u043b\u0438\u0431\u043e FormGroup, \u043b\u0438\u0431\u043e FormArray, \u0442.\u0435. \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430, \u0430 \u043d\u0435 \u0432\u0441\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435. \u041d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043f\u043e\u043b\u0435 valid \/ invalid<br \/>  \u2022 <b>informationMessages<\/b>: ValidationEvent[] \u2014 \u043f\u043e\u043b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u00ab\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u00bb. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439, \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u043b\u0438\u0431\u043e FormControl, \u043b\u0438\u0431\u043e FormGroup, \u043b\u0438\u0431\u043e FormArray, \u0442.\u0435. \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430, \u0430 \u043d\u0435 \u0432\u0441\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435. \u041d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043f\u043e\u043b\u0435 valid \/ invalid<br \/>  \u2022 <b>successes<\/b>: ValidationEvent \u2014 \u043f\u043e\u043b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439, \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u043b\u0438\u0431\u043e FormControl, \u043b\u0438\u0431\u043e FormGroup, \u043b\u0438\u0431\u043e FormArray, \u0442.\u0435. \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430, \u0430 \u043d\u0435 \u0432\u0441\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435. \u041d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043f\u043e\u043b\u0435 valid \/ invalid<br \/>  \u2022 <b>maxEventLevel<\/b>() \u2013 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445 \u0432 \u043f\u043e\u043b\u0435 \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442.<br \/>  \u2022 \u041c\u0435\u0442\u043e\u0434 \u0432\u0435\u0440\u043d\u0435\u0442 \u043e\u0434\u043d\u043e \u0438\u0437 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 enum, \u0432 \u0441\u043b\u0435\u0434\u044f\u0449\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0435.<br \/>   1. ValidationEventTypes.Error;<br \/>   2. ValidationEventTypes.Warning;<br \/>   3. ValidationEventTypes.Info;<br \/>   4. ValidationEventTypes.Success;<\/p>\n<p>  \u2022 <b>serverErrors<\/b>: string[] \u2013 \u043f\u043e\u0441\u043b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u0442\u043e\u043d\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 \u0444\u043e\u0440\u043c\u044b \u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0444\u043e\u0440\u043c\u044b, \u0438 \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u044d\u0442\u0438\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 serverErrors. \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e serverErrors \u2013 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u043f\u043e\u0442\u0435\u0440\u0435 \u0444\u043e\u043a\u0443\u0441\u0430 \u0441 \u043f\u043e\u043b\u044f \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u044b\u043b\u0438 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0435 \u0431\u044b\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043e.<br \/>  \u2022 <b>setDirty(dirty: boolean)<\/b>: void \u2013 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 pristine \/ dirty<br \/>  \u2022 <b>setTouched(touched: boolean)<\/b>: void \u2013 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 untouched \/ touched<br \/>  \u2022 <b>setFocused()<\/b>: void \u2013 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f focused (\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f FormControl)<br \/>  \u2022 <b>dispose()<\/b>: void \u2013 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d \u043a \u0432\u044b\u0437\u043e\u0432\u0443 \u0432 componentWillUnmount \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0433\u043e \u0437\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443.<\/p>\n<p>  \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435.<br \/>  \u041f\u043e\u043b\u044f valid \u0438 invalid \u0432 FormGroup \u0438 FormArray \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.<br \/>  \u0418 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0432 \u0441\u0430\u043c\u044b\u0439 \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 \u043d\u0438\u0436\u0435\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0444\u043e\u0440\u043c\u044b.<br \/>  \u041d\u041e! \u0423\u0437\u043b\u044b FormGroup \u0438 FormArray \u0438\u043c\u0435\u044e\u0442 <b>c\u0432\u043e\u0439<\/b> \u043d\u0430\u0431\u043e\u0440 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0448\u0438\u0431\u043e\u043a (errors, warnings, informationMessages, successes). \u0422.\u0435. \u0435\u0441\u043b\u0438 \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0443 FormGroup errors \u2013 \u043e\u043d\u0430 \u0432\u044b\u0434\u0430\u0441\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u043e\u0438 \u043e\u0448\u0438\u0431\u043a\u0438, \u043d\u043e \u043d\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0430 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u043c FormControl.<\/p>\n<h2>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h2>\n<p>  \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 mobx-form-validation-kit \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043d\u043e \u0432 \u043d\u0435\u0439 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440.<br \/>  \u2022 <b>requiredValidator<\/b> \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0440\u0430\u0432\u043d\u043e null, \u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0430 \u043f\u0443\u0441\u0442\u043e\u0442\u0443.<br \/>  \u2022 <b>notEmptyOrSpacesValidator<\/b> \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0440\u0430\u0432\u043d\u043e null, \u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0430 \u043f\u0443\u0441\u0442\u043e\u0442\u0443 \u0438\u043b\u0438 \u0447\u0442\u043e \u043e\u043d\u0430 \u043d\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043e\u0434\u043d\u0438\u0445 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432.<br \/>  \u2022 <b>notContainSpacesValidator<\/b> \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432.<br \/>  \u2022 <b>patternValidator<\/b> \u2013 \u0432\u044b\u0434\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443<br \/>  \u2022 <b>invertPatternValidator<\/b> \u2014 \u0432\u044b\u0434\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443<br \/>  \u2022 <b>minLengthValidator<\/b> \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0430 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043b\u0438\u043d\u0443<br \/>  \u2022 <b>maxLengthValidator<\/b> \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043b\u0438\u043d\u0443<br \/>  \u2022 <b>absoluteLengthValidator<\/b> \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0434\u043b\u0438\u043d\u0443<br \/>  \u2022 <b>isEqualValidator<\/b> \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043d\u0430 \u0442\u043e\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<br \/>  \u2022 <b>compareValidator<\/b> \u2014 \u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (\u043e\u0448\u0438\u0431\u043a\u0430, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u0435\u0440\u043d\u0443\u043b\u0430 false)<br \/>  \u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438.  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b>  <\/p>\n<pre><code class=\"javascript\">   this.form = new FormGroup&lt;FormRegistration&gt;({       firstName: new FormControl&lt;string&gt;(&quot;&quot;, {         validators: [requiredValidator()],       }),       lastName: new FormControl&lt;string&gt;(&quot;&quot;, {         validators: [requiredValidator()],       }),       email: new FormControl&lt;string&gt;(&quot;&quot;, {         validators: [requiredValidator()],       }),       age: new FormControl&lt;string&gt;(&quot;&quot;),     }); <\/code><\/pre>\n<p>  \u0421\u0435\u0439\u0447\u0430\u0441 firstName \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c \u0435\u0433\u043e \u0434\u043b\u0438\u043d\u0443 \u0438 \u0441\u043a\u0430\u0436\u0435\u043c \u0447\u0442\u043e \u043f\u043e\u043b\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u0435\u043b\u044b.  <\/p>\n<pre><code class=\"javascript\">       firstName: new FormControl&lt;string&gt;(&quot;&quot;, {         validators: [           requiredValidator(),           minLengthValidator(2),           maxLengthValidator(5),           notContainSpacesValidator()         ],       }), <\/code><\/pre>\n<p>  \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0438\u043c. <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/u4\/5s\/tl\/u45stl5mtay6ppdrytz8i7grmae.png\">  <\/p>\n<hr>\n<p>  <b>Flutter<\/b>  <\/p>\n<pre><code class=\"dart\"> this.form = FormGroup(RegistrationForm(       firstName: FormControl(           value: &quot;&quot;,           options: OptionsFormControl(validators: [             requiredValidator(),             minLengthValidator(2),             maxLengthValidator(5),             notContainSpacesValidator()           ])),       lastName: FormControl(           value: &quot;&quot;,           options: OptionsFormControl(validators: [requiredValidator()])),       email: FormControl(           value: &quot;&quot;,           options: OptionsFormControl(validators: [requiredValidator()])),       age: FormControl(           value: &quot;&quot;,           options: OptionsFormControl(validators: [requiredValidator()])),     )); <\/code><\/pre>\n<p>  \u0421\u0435\u0439\u0447\u0430\u0441 firstName \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c \u0435\u0433\u043e \u0434\u043b\u0438\u043d\u0443 \u0438 \u0441\u043a\u0430\u0436\u0435\u043c \u0447\u0442\u043e \u043f\u043e\u043b\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u0435\u043b\u044b.  <\/p>\n<pre><code class=\"dart\"> options: OptionsFormControl(validators: [             requiredValidator(),             minLengthValidator(2),             maxLengthValidator(5),             notContainSpacesValidator()           ]) <\/code><\/pre>\n<p>  \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0438\u043c. <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ej\/6u\/k9\/ej6uk9kfvehv-uyfsaxrph9hdiw.png\"><br \/>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0432\u0441\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435. \u041d\u043e \u0447\u0430\u0441\u0442\u043e \u0431\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a \u0445\u043e\u0447\u0435\u0442 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0443 \u043e\u0448\u0438\u0431\u043a\u0443, \u0430 \u043d\u0435 \u0432\u0441\u0435 \u0441\u0440\u0430\u0437\u0443. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0422\u0417 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0442\u0430\u043a, \u0447\u0442\u043e \u043e\u0434\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043f\u0440\u043e\u0448\u043b\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f.<br \/>  \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0435\u0440\u0442\u043a\u0430 <b>wrapperSequentialCheck<\/b>. \u0415\u0451 \u0432\u044b\u0437\u043e\u0432 \u0438 \u0435\u0451 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430, \u043d\u043e \u043d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0442.\u0435. \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u043f\u0440\u043e\u0448\u043b\u0430 \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a.<br \/>  \u0412\u0442\u043e\u0440\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u043e\u043c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439. <b>wrapperActivateValidation<\/b> \u043f\u0435\u0440\u0432\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 activate \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 FormControl \u0434\u0430\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043e\u0431\u0449\u0438\u0439 \u0431\u0438\u043b\u0434\u0435\u0440 \u0434\u043b\u044f \u0446\u0435\u043b\u043e\u0439 \u0444\u043e\u0440\u043c\u044b FormGroup \u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439, \u0438 \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u0449\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u043b\u0435\u0439. \u041d\u043e \u0432\u043e\u0442 \u0437\u0430\u0433\u0432\u043e\u0437\u0434\u043a\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0445\u043e\u0442\u044c \u0444\u043e\u0440\u043c\u0430 \u0438 \u043e\u0434\u043d\u0430, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u00ab\u0442\u0438\u043f\u0430 \u043f\u043b\u0430\u0442\u0435\u0436\u0430\u00bb \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e. \u0422\u0430\u043a \u0432\u043e\u0442 <b>wrapperActivateValidation<\/b> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0443\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0438\u043f\u0430 \u043f\u043b\u0430\u0442\u0435\u0436\u0430.<\/p>\n<hr>\n<p>  <b>TypeScript<\/b>  <\/p>\n<pre><code class=\"javascript\"> firstName: new FormControl&lt;string&gt;(&quot;&quot;, {         validators: [           wrapperSequentialCheck([             requiredValidator(),             minLengthValidator(2),             maxLengthValidator(5),             notContainSpacesValidator(),           ]),         ],       }),<\/code><\/pre>\n<p>  <\/p>\n<hr>\n<p>  <b>Flutter<\/b>  <\/p>\n<pre><code class=\"dart\">firstName: FormControl(           value: &quot;&quot;,           options: OptionsFormControl(validators: [             wrapperSequentialCheck([               requiredValidator(),               minLengthValidator(2),               maxLengthValidator(5),               notContainSpacesValidator()             ])           ])) <\/code><\/pre>\n<p>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u0412 \u043e\u0431\u0449\u0435\u043c \u0438 \u0446\u0435\u043b\u043e\u043c \u043c\u044b \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u0435\u043c \u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435. \u0418 \u043d\u0430\u043c \u0434\u0430\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043e\u0442\u043a\u0443\u0434\u0430 \u0438 \u043a\u0443\u0434\u0430 \u0438\u0434\u0435\u0442.<br \/>  \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0432\u043e\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438.<br \/>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0434\u043b\u044f \u043f\u0435\u0440\u0438\u043e\u0434\u0430 \u0434\u0430\u0442.  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b>  <\/p>\n<pre><code class=\"javascript\">interface FormRange extends ControlsCollection {   min: FormControl&lt;Date&gt;;   max: FormControl&lt;Date&gt;; }  interface FormRegistration extends ControlsCollection {   firstName: FormControl&lt;string&gt;;   lastName: FormControl&lt;string&gt;;   email: FormControl&lt;string&gt;;   age: FormControl&lt;string&gt;;   dateRange: FormGroup&lt;FormRange&gt;; } <\/code><\/pre>\n<pre><code class=\"javascript\">this.form = new FormGroup&lt;FormRegistration&gt;({ \u2026       dateRange: new FormGroup&lt;FormRange&gt;(         {           min: new FormControl&lt;Date&gt;(new Date()),           max: new FormControl&lt;Date&gt;(new Date()),         },         {           validators: [             async (group: FormGroup&lt;FormRange&gt;): Promise&lt;ValidationEvent[]&gt; =&gt; { if (group.controls.max.value &lt; group.controls.min.value) {                 return [                   {                     message: '\u0414\u0430\u0442\u0430 &quot;\u043e\u0442&quot; \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0430\u0442\u044b &quot;\u0434\u043e&quot;',                     type: ValidationEventTypes.Error,                   },                 ];               }               return [];            },           ],         }       ),     }); <\/code><\/pre>\n<p>  <\/p>\n<hr>\n<p>  <b>Flutter<\/b>  <\/p>\n<pre><code class=\"dart\"> class FormRange extends ControlsCollection {   final FormControl&lt;DateTime&gt; min;   final FormControl&lt;DateTime&gt; max;   FormRange({this.min, this.max});   @override   Iterable&lt;AbstractControl&gt; allFields() =&gt; [this.min, this.max]; }  class RegistrationForm extends ControlsCollection { \u2026   RegistrationForm(       {this.firstName, this.lastName, this.email, this.age, this.dateRange});    @override   Iterable&lt;AbstractControl&gt; allFields() =&gt;       [this.firstName, this.lastName, this.email, this.age, this.dateRange]; } <\/code><\/pre>\n<pre><code class=\"dart\">this.form = FormGroup(RegistrationForm( \u2026       dateRange: FormGroup&lt;FormRange&gt;(           FormRange(               min: FormControl&lt;DateTime&gt;(value: DateTime.now()),               max: FormControl&lt;DateTime&gt;(value: DateTime.now())),           options: OptionsFormGroup&lt;FormRange&gt;(validators: [             (FormGroup&lt;FormRange&gt; group) async {               if (group.controls.max.value.isBefore(group.controls.min.value)) {                 return [                   ValidationEvent(                     message: '\u0414\u0430\u0442\u0430 &quot;\u043e\u0442&quot; \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0430\u0442\u044b &quot;\u0434\u043e&quot;',                     type: ValidationEventTypes.Error,                   )                 ];               }               return [];             },           ])),     ));<\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u044b\u043c \u0441 \u0442\u0438\u043f\u0430\u043c\u0438. Flutter \u0445\u043b\u0435\u0431\u043e\u043c \u043d\u0435 \u043a\u043e\u0440\u043c\u0438, \u043d\u043e \u0434\u0430\u0439 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043e\u0448\u0438\u0431\u043a\u0443, \u0447\u0442\u043e subtype \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439\u2026<br \/>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0432\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 [\u0445\u043e\u0442\u044f \u0442\u0430\u043a \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e], \u0430 \u0432\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u0441\u044e \u0433\u0440\u0443\u043f\u043f\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043b\u0438\u0448\u044c \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435.<\/p>\n<h2>\u041a\u043d\u043e\u043f\u043a\u0430 \u00abSubmit\u00bb<\/h2>\n<p>  \u0423\u0441\u0442\u0430\u043b\u0438? \ud83d\ude42 \u0414\u0430, \u044f \u0442\u043e\u0436\u0435\u2026 \u0423\u0436\u0435 \u0438\u0434\u0435\u0442 20-\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u0435\u0449\u0435 \u043c\u043d\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u043e \u0447\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043b\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b.<br \/>  \u041d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0441\u0438\u043b\u0438\u043c, \u043b\u0438\u0448\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043c\u043e\u043c\u0435\u043d\u0442, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c\u00bb<br \/>  \u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043f\u043e \u043a\u043d\u043e\u043f\u043a\u0435 \u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u2013 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0438 \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 \u043d\u0430 \u0444\u043e\u043a\u0443\u0441.  <\/p>\n<hr>\n<p>  <b>TypeScript<\/b>  <\/p>\n<pre><code class=\"javascript\">\u2026 await this.form.wait();  if (this.form.invalid) {  this.form.setTouched(true);   const firstError = this.form.allControls().find(c =&gt; c.invalid &amp;&amp; !!c.element);  if (!!firstError) {     firstError.element.focus();   }  \u2026 } <\/code><\/pre>\n<p>  <\/p>\n<hr>\n<p>  <b>Flutter<\/b>  <\/p>\n<pre><code class=\"javascript\">\u2026 await this.form.wait();     if (this.form.invalid) {       this.form.setTouched(true);       final firstError = this.form.allControls().firstWhere((c) =&gt; c.invalid);       firstError.focusNode.requestFocus();     } \u2026 <\/code><\/pre>\n<p>  ^^^^^^^  <\/p>\n<hr>\n<p>  \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0434\u0435\u0441\u044c, \u044d\u0442\u043e \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0441\u0435\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439.<br \/>  <i>await this.form.wait();<\/i><br \/>  \u0414\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043e\u0431\u0449\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u044c, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0435\u0449\u0435 \u0438 \u043a\u0443\u0440\u0441\u043e\u0440 \u0441\u0442\u0430\u0432\u0438\u043c \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e.<br \/>  \u0418 \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u0442\u0441\u044f, \u0432\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432 Store, \u0430 \u043a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u043b\u044e\u0434\u0438. \u0418 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043a\u0440\u0430\u043d\u0447\u0430 \u2013 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0434\u0435\u043b\u043e, \u0447\u0442\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u043d\u0430\u0431\u043e\u0440 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0415\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u044b.<br \/>  \u2022 \u0427\u0442\u043e \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0433\u0434\u0430 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043d\u043e \u0438 \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0430\u0441\u044c observable \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438.<br \/>  \u2022 \u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 active<br \/>  \u2022 \u0427\u0442\u043e FormControl \u043c\u043e\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u043d\u043e \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0418 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f.<br \/>  \u2022 \u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 FormArray<br \/>  \u2022 \u041a\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e observable \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u044d\u0442\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438.<br \/>  \u0418 \u0435\u0449\u0435 \u043a\u0443\u0447\u0443 \u0432\u0441\u0435\u0433\u043e, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043f\u0430\u043a\u0435\u0442 mobx-form-validation-kit.<br \/>  \u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u0430\u043c \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u044d\u0442\u043e \u0441\u0442\u0430\u0442\u044c\u044f \u0441\u0442\u0430\u043b\u0430 \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0447\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0435\u0451 \u0432\u0430\u0440\u0438\u0430\u043d\u0442. <\/p>\n<p>  \u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u0441\u0442\u0430\u0442\u044c\u044e \u0434\u043e \u043a\u043e\u043d\u0446\u0430. \u0418 \u044f \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e mobx-form-validation-kit \u0441\u0442\u0430\u043d\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 mobx \u043d\u0430 React (TypeScript) \u0438\u043b\u0438 Flutter.<br \/>   \u2014 \u041f.\u0441.<br \/>  \u0415\u0441\u043b\u0438 \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u2013 \u043f\u0438\u0448\u0438\u0442\u0435, \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c \ud83d\ude42<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/537070\/\"> https:\/\/habr.com\/ru\/post\/537070\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<h2>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>  \u041f\u043e\u0447\u0442\u0438 \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043f\u0435\u0440\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 &quot;<a href=\"https:\/\/habr.com\/ru\/post\/470537\/\">\u041d\u043e\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439 \u0434\u043b\u044f React \u043d\u0430 Mobx @quantumart\/mobx-form-validation-kit<\/a>&quot;<br \/>  \u0412\u0440\u0435\u043c\u044f \u0448\u043b\u043e, \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0438 \u043d\u0435 \u0441\u0442\u043e\u044f\u043b\u0430 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435, \u0434\u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043a\u0430\u043a \u0438 \u043d\u0430\u0448\u0435 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435 \u0432 \u0446\u0435\u043b\u043e\u043c. \u041c\u044b \u043f\u0435\u0440\u0435\u0448\u043b\u0438 \u043d\u0430 flutter, \u043f\u043e \u043f\u0443\u0442\u0438 \u043f\u043e\u043f\u0438\u043d\u0430\u0432 ReactNative, \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0418 \u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u0438 \u043e\u0442 \u043d\u0430\u0441 \u043d\u043e\u0432\u044b\u0445 \u0438 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043f\u0435\u0440\u0435\u0440\u0430\u0431\u043e\u0442\u043a\u0438 mobx-form-validation-kit.<br \/>  \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0440\u0430\u0434 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u043c \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u0430\u043a\u0435\u0442\u0430 mobx-form-validation-kit.<br \/>  \u0414\u043b\u044f \u0441\u0442\u0440\u043e\u0433\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e TypeScript<br \/>  <a href=\"https:\/\/www.npmjs.com\/package\/@quantumart\/mobx-form-validation-kit\" rel=\"nofollow\">mobx-form-validation-kit 2.0<\/a><br \/>  \u0418 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043f\u043e\u0434 Flutter<br \/>  <a href=\"https:\/\/pub.dev\/packages\/flutter_mobx_form_validation_kit\" rel=\"nofollow\"> flutter_mobx_form_validation_kit 2.0<\/a><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/sg\/cx\/qb\/sgcxqbdh_qdnifgudrwwnuhdvrq.png\">  <\/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-316324","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/316324","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=316324"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/316324\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=316324"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=316324"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=316324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}