рд╕рд┐рдореНрдлрдиреА 2 рдФрд░ рдиреЙрдХрдЖрдЙрдЯ рдЬреЗрдПрд╕ - рдлреЙрд░реНрдо рд╕рддреНрдпрд╛рдкрди

рдХреБрдЫ рдорд╣реАрдиреЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рд▓реЛрдХрдкреНрд░рд┐рдп Symfony2 PHP рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реАрдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореБрдЭреЗ рдиреЙрдХрдЖрдЙрдЯJS рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рддрд░рдл рд╕реЗ рдлреЙрд░реНрдо рднрд░рдиреЗ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рдо рдорд┐рд▓рд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рддреНрдпрд╛рдкрди рдХреЗ рдирд┐рдпрдо, рдЗрд╕рд▓рд┐рдП рдХреЛрдб рджреЛрд╣рд░рд╛рд╡ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдирд╣реАрдВ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрдХрд╛рдИ рд╡рд░реНрдЧ рд╕реЗ рд╕рд┐рдореНрдлрдиреА рд▓реЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреА рдЬрд╛рддреА рд╣реИред
рд╕рдорд╕реНрдпрд╛ рдХреЗ рдХрд┐рд╕реА рдПрдХ рдкрдХреНрд╖ рдХреЛ рдХрд╡рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ 10,000 рд╕реЗ рдЕрдзрд┐рдХ рдкреНрд▓рдЧрдЗрдиреНрд╕, рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдФрд░ рдмрдВрдбрд▓ рд╣реИрдВред рдореБрдЭреЗ рдЗрд╕рдХрд╛ рд╡реНрдпрд╛рдкрдХ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдорд┐рд▓рд╛ред рдХрд╛рд░реНрдп рдХреЗ рдкрд╣рд▓реЗ рдФрд░ рджреВрд╕рд░реЗ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рджреЛ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рд╕рдорд╛рдзрд╛рдиреЛрдВ (рдиреЙрдХрдЖрдЙрдЯ-рд╡реИрд▓рд┐рдбреЗрд╢рди рдФрд░ APYJsFormValidationBundle) рдХреЗ рд╕рдВрдпреЛрдЬрди рдХреА рд╢реНрд░рдорд╕рд╛рдзреНрдпрддрд╛ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдЦрд░реЛрдВрдЪ рд╕реЗ рд╕рдм рдХреБрдЫ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдХрдЯ рдХреЗ рддрд╣рдд рд╡рд┐рд╡рд░рдгред

рд╕рд┐рдореНрдлрдиреА 2 рдореЗрдВ рдорд╛рдиреНрдпрддрд╛

рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рддреНрдпрд╛рдкрди рдирд┐рдпрдо рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВред рд╕реНрдореГрддрд┐ рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдПрдХ рд╕реВрдЪреА рджреВрдВрдЧрд╛:

/** * Acme\UsersBundle\Entity\User */ class User implements JsonSerializable { /** * @var string $name . * * @ORM\Column(name="name", type="string", length=255, unique = true, nullable=false) * * @Assert\NotBlank(message=" ") * @Assert\MinLength(limit=3, message="  ") * @Assert\MaxLength(limit=15, message="  ") * @Assert\Regex(pattern="/^[A-z0-9_-]+$/ui", match=true, message="   ") */ private $name; // .... } 

рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЗрди рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░реЗрдВред рдмреЗрд╢рдХ, рдврд╛рдВрдЪрд╛ рдЦреБрдж рд╣реА рдРрд╕рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдкрд░рд┐рдгрд╛рдо рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ "рдРрдк / рдХреИрд╢ / рджреЗрд╡ / рдПрдиреЛрдЯреЗрд╢рди /" рдпрд╛ "рдРрдк / рдХреИрд╢ / рдкреНрд░реЛрдбрдХреНрд╢рди / рдПрдиреЛрдЯреЗрд╢рди /" рдкрддреЗ рдкрд░ рдХреИрд╢ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдереЛрдбрд╝рд╛ рд╕реЛрдЪрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдПрдХ рдЫреЛрдЯрд╛ рддрд░реАрдХрд╛ рд▓рд┐рдЦрд╛:

 /** *    . * * @param string $bundle    "Bundle". * @param string $entity         . * @param string $env  ("dev"  "prod"). * @param string $namespace   (  "Acme"). * @return array . */ private function readEntityAnnotations($bundle, $entity, $env = 'prod', $namespace = 'Acme') { $result = array(); $files = glob($_SERVER['DOCUMENT_ROOT'] . '/../app/cache/' . $env . '/annotations/' . $namespace . '-' . $bundle .'Bundle-Entity-' . $bundle . $entity .'$*.php'); foreach ($files as $path) { //        preg_match('/\\$(.*?)\\./', $path, $matches); //   foreach (include $path as $annotation) { //       if (get_parent_class($annotation) === 'Symfony\\Component\\Validator\\Constraint') { $type = preg_replace('/^.*\\\/', '', get_class($annotation)); $annotation = (array)$annotation; unset($annotation['charset']); $result[$matches[1]][$type] = (array)$annotation; } } } return $result; } 

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

рдирддреАрдЬрддрди, рд╣рдо рдЧреНрд░рд╛рд╣рдХ рдкрд░ рдХреБрдЫ рд╕рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
рдПрдиреЛрдЯреЗрд╢рди

рдорд╛рдиреНрдпрддрд╛ рдФрд░ рдиреЙрдХрдЖрдЙрдЯ рдЬреЗ.рдПрд╕.

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

 var myComplexValue = ko.observable() myComplexValue.extend({ required: true }) .extend({ minLength: 42 }) .extend({ pattern: { message: 'Hey this doesnt match my pattern', params: '^[A-Z0-9].$' }}); 

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

var name = ko.observable('habrahabr').extend({MinLength: 42});

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

рдЕрдм рд╣рдо рдЦреБрдж рд╣реА рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:

 ko.extenders.MinLength = function(observavle, params) { // .... }; 

рд╡рд┐рдЪрд╛рд░ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдЖрдЗрдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝реЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЙрдбрд▓ рд▓реЗрдВ:

 var AppViewModel = new (function () { var self = this; //     this.name = ko.observable(''); //   this.mail = ko.observable(''); // E-mail //   ko.validation.init(self, _ANNOTATIONS_); //    this.submit = function () { if (self.isValid()) { alert(' '); } else { alert('  '); } }; })(); 

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

 <form action="#"> <p> <label for=""></label> <input type="text" data-bind="value: name, valueUpdate: 'keyup'"> <span data-bind="visible: name.isError, text: name.message"></span> </p> <p> <label for="">E-mail</label> <input type="text" data-bind="value: mail, valueUpdate: 'keyup'"> <span data-bind="visible: mail.isError, text: mail.message"></span> </p> <button data-bind="click: submit"></button> </form> 

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

 AppViewModel.name.isError = ko.observable(); //    AppViewModel.name.message = ko.observable(); //    AppViewModel.name.typeError = ''; //    

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

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

рдЕрдм рдореИрдВ рдкреВрд░рд╛ рдХреЛрдб рджреВрдВрдЧрд╛, рдФрд░ рдлрд┐рд░ рдореИрдВ рдЗрд╕рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВрдВрдЧрд╛:

 ko.validation = new (function () { /** *   . * @return {Boolean} */ var isValid = function () { this.validate(true); //      for (var opt in this) if (ko.isObservable(this[opt])) { //     if (this[opt].isError !== undefined && this[opt].isError() === true) { return false; } } return true; }; return { /** *  . * @param {object} AppViewModel  . * @param {object} annotations   . */ init: function (AppViewModel, annotations) { var asserts, options; AppViewModel.validate = ko.observable(false); //        for (var field in annotations) if (annotations.hasOwnProperty(field)) { asserts = annotations[field]; //   (AppViewModel)        if (AppViewModel[field] !== undefined && ko.isObservable(AppViewModel[field])) { AppViewModel[field].isError = ko.observable(); //    AppViewModel[field].message = ko.observable(); //    //      for (var i in asserts) if (asserts.hasOwnProperty(i)) { options = {}; options[i] = asserts[i]; //   options[i]['asserts'] = asserts; //    options[i]['AppViewModel'] = AppViewModel; //    //      AppViewModel[field].extend(options); } } } //      AppViewModel.isValid = isValid; }, /** *    . * @param name  . * @param validate  . * @param checkAsserts */ addAssert: function (name, validate, checkAsserts) { //  extender' ko.extenders[name] = function(target, option) { //     "AppViewModel.validate" ko.computed(function () { //          if (validate(target, option) === false && option.AppViewModel.validate()) { checkAsserts = checkAsserts || new Function('t,o', 'return false'); //     if (checkAsserts(target, option) === false) { target.isError(true); //    target.message(option.message); //    target.typeError = name; //   } return; } //          if (target.isError.peek() === true && target.typeError === name) { target.isError(false); } }); return target; }; } } })(); 

рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЛ рддреБрд░рдВрдд рдЬреЛрдбрд╝реЗрдВ:

 // NotBlank ko.validation.addAssert('NotBlank', function (target, option) { return (target().length > 0); }); // MaxLength ko.validation.addAssert('MaxLength', function (target, option) { return (target().length <= option.limit); }); 


рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдХрд░рдг

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

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

Init рд╡рд┐рдзрд┐ рд╕рддреНрдпрд╛рдкрди рдкреНрд░рд╛рд░рдВрднрд┐рдХ
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╡рд┐рдзрд┐ рдЙрдкрд░реНрдпреБрдХреНрдд рдорд╛рдиреНрдп рд╕рдВрдкрддреНрддрд┐ рдФрд░ рдКрдкрд░ рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП isValid рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЙрд╕ рдЪрдХреНрд░ рдХреЗ рдмрд╛рдж рдпрд╣ рдЙрди рдХреНрд╖реЗрддреНрд░реЛрдВ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрдВрдз рдЗрдВрдЧрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдирд╛рдо рдХреЗ рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рдЧреБрдг рд╣реЛрддреЗ рд╣реИрдВ, рдореЙрдбрд▓ рдореЗрдВ рдЕрдВрддрд┐рдо рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ: isError рдФрд░ рд╕рдВрджреЗрд╢ред рджреВрд╕рд░рд╛, рдиреЗрд╕реНрдЯреЗрдб рд▓реВрдк рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рдХреЗ рд╕рд╛рде рдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИред рдПрдХ рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ, рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕рд┐рдореНрдлрдиреА рдХреИрд╢ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдкреНрд░рддрд┐рдмрдВрдз рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдореЙрдбрд▓ (AppViewModel) рдХреЗ рд▓рд┐рдВрдХ рдФрд░ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рд╕рднреА рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЗ рд╕рд╛рдеред

AddAssert рд╡рд┐рдзрд┐ред рдПрдХ рдирдпрд╛ рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдзрд┐ рдХрд╛ рдкрдВрдЬреАрдХрд░рдг
рд╡рд┐рдзрд┐ рддреАрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд▓реЗрддреА рд╣реИ: рдирд╛рдо - рдирдИ рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдзрд┐ рдХрд╛ рдирд╛рдо, рд╕рддреНрдпрд╛рдкрди - рд╕рддреНрдпрд╛рдкрди рд╕рдорд╛рд░реЛрд╣, рдЬрд╛рдБрдЪрдХрд░реНрддрд╛ - рддреНрд░реБрдЯрд┐ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдлрд╝рдВрдХреНрд╢рдиред рд╣рдо рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рдереЛрдбрд╝рд╛ рдмрд╛рдж рдореЗрдВ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред
рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рд╡рд┐рдзрд┐ рдХрд╛ рдирд┐рдХрд╛рдп рдПрдХ рдЕрдиреБрдорд╛рдирд┐рдд рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рд▓рд┐рдкрдЯреЗ рд╣реБрдП рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХреЗ рдХрд┐ AppViewModel.validate рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╕рдордп рд╕рддреНрдпрд╛рдкрди рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛред

CheckAsserts рд╡рд┐рдзрд┐
рдпрд╣ AddAssert рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИред рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рддреНрд░реБрдЯрд┐ рдХрд░реЗрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рдлрд╝реАрд▓реНрдб рдореЗрдВ рджрд░реНрдЬ рдХреА рдЧрдИ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд▓рдВрдмрд╛рдИ рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╕рдордпред рдпрджрд┐ рдлрд╝реАрд▓реНрдб рдЦрд╛рд▓реА рд╣реИ, рддреЛ рдореИрдВ рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ "рдлрд╝реАрд▓реНрдб рднрд░реЗрдВ", рдФрд░ рдпрджрд┐ рдпрд╣ 3 рд╡рд░реНрдгреЛрдВ рд╕реЗ рдХрдо рд▓рдВрдмрд╛ рд╣реИ - "рдирд╛рдо рдореЗрдВ рдХрдо рд╕реЗ рдХрдо 3 рд╡рд░реНрдг рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП", рдЖрджрд┐ред рд▓реЗрдХрд┐рди рдЗрд╕ рдмрд╛рдд рдХреА рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ рдХрд┐ NotLlank рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╛рдж рдореЗрдВ MinLength рдХреА рдЬрд╛рдВрдЪ рд╣реЛрдЧреАред рдпрд╣рд╛рдБ MinLengt рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдзрд┐ (рдПрдХреНрд╕рдЯреЗрдВрдбрд░) рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:

 // MinLength ko.validation.addAssert( 'MinLength', function (target, option) { return (target().length >= option.limit); }, function (target, option) { //       "NotBlank" return (target().length === 0 && option.asserts.NotBlank !== undefined); } ); 

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

рдХреЗ рдЙрдкрдпреЛрдЧ

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

рдХреЛрдбрдкреЗрди рдкрд░ рдПрдХ рдЫреЛрдЯрд╛ рдбреЗрдореЛ рд╣реИ: codepen.io/alexismaster/pen/LAaqc

рдЕрдВрдд рдореЗрдВ, readEntityAnnotations рд╡рд┐рдзрд┐ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд╛ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ред рдЖрдк рд╕рддреНрдпрд╛рдкрди рд╕реЗрд╡рд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдиреЛрдЯреЗрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 //      "name"   "User" $validator = $this->get('validator'); $metadata = $validator->getMetadataFactory()->getClassMetadata("Acme\\UsersBundle\\Entity\\User"); var_dump($metadata->properties['name']->constraints); 


рд╕рдВрджрд░реНрдн:
github.com/Abhoryo/APYJsFormValidationBundle - рд╕рд┐рдореНрдлрдиреА рдмрдВрдбрд▓ рдЬреЗрдПрд╕ рдХреЛрдб рдХреЛ рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рдЬрдирд░реЗрдЯ рдХрд░ рд░рд╣рд╛ рд╣реИ
github.com/Knockout-Contrib/Knockout-Validation
habrahabr.ru/post/136782 - рдиреЙрдХрдЖрдЙрдЯ рдЬреЗрдПрд╕ рдФрд░ рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдкреЛрд╕реНрдЯ
phalcon-docs-ru.readthedocs.org/ru/latest/reference/annotations.html - рдПрдиреЛрдЯреЗрд╢рди рдкрд╛рд░реНрд╕рд░
habrahabr.ru/post/133270 - рд╕рд┐рдореНрдлрдиреА 2 рдореЗрдВ рдХрд╕реНрдЯрдо рдПрдиреЛрдЯреЗрд╢рди

Source: https://habr.com/ru/post/In188720/


All Articles