рдХреБрдЫ рдорд╣реАрдиреЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рд▓реЛрдХрдкреНрд░рд┐рдп Symfony2 PHP рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реАрдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореБрдЭреЗ рдиреЙрдХрдЖрдЙрдЯJS рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рддрд░рдл рд╕реЗ рдлреЙрд░реНрдо рднрд░рдиреЗ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рдо рдорд┐рд▓рд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рддреНрдпрд╛рдкрди рдХреЗ рдирд┐рдпрдо, рдЗрд╕рд▓рд┐рдП рдХреЛрдб рджреЛрд╣рд░рд╛рд╡ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдирд╣реАрдВ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрдХрд╛рдИ рд╡рд░реНрдЧ рд╕реЗ рд╕рд┐рдореНрдлрдиреА рд▓реЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреА рдЬрд╛рддреА рд╣реИред
рд╕рдорд╕реНрдпрд╛ рдХреЗ рдХрд┐рд╕реА рдПрдХ рдкрдХреНрд╖ рдХреЛ рдХрд╡рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ 10,000 рд╕реЗ рдЕрдзрд┐рдХ рдкреНрд▓рдЧрдЗрдиреНрд╕, рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдФрд░ рдмрдВрдбрд▓ рд╣реИрдВред рдореБрдЭреЗ рдЗрд╕рдХрд╛ рд╡реНрдпрд╛рдкрдХ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдорд┐рд▓рд╛ред рдХрд╛рд░реНрдп рдХреЗ рдкрд╣рд▓реЗ рдФрд░ рджреВрд╕рд░реЗ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рджреЛ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рд╕рдорд╛рдзрд╛рдиреЛрдВ (рдиреЙрдХрдЖрдЙрдЯ-рд╡реИрд▓рд┐рдбреЗрд╢рди рдФрд░ APYJsFormValidationBundle) рдХреЗ рд╕рдВрдпреЛрдЬрди рдХреА рд╢реНрд░рдорд╕рд╛рдзреНрдпрддрд╛ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдЦрд░реЛрдВрдЪ рд╕реЗ рд╕рдм рдХреБрдЫ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдХрдЯ рдХреЗ рддрд╣рдд рд╡рд┐рд╡рд░рдгред
рд╕рд┐рдореНрдлрдиреА 2 рдореЗрдВ рдорд╛рдиреНрдпрддрд╛
рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рддреНрдпрд╛рдкрди рдирд┐рдпрдо рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВред рд╕реНрдореГрддрд┐ рдХреЛ рддрд╛рдЬрд╝рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдПрдХ рд╕реВрдЪреА рджреВрдВрдЧрд╛:
class User implements JsonSerializable { private $name;
рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЗрди рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░реЗрдВред рдмреЗрд╢рдХ, рдврд╛рдВрдЪрд╛ рдЦреБрдж рд╣реА рдРрд╕рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдкрд░рд┐рдгрд╛рдо рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ "рдРрдк / рдХреИрд╢ /
рджреЗрд╡ / рдПрдиреЛрдЯреЗрд╢рди /" рдпрд╛ "рдРрдк / рдХреИрд╢ /
рдкреНрд░реЛрдбрдХреНрд╢рди / рдПрдиреЛрдЯреЗрд╢рди /" рдкрддреЗ рдкрд░ рдХреИрд╢ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдереЛрдбрд╝рд╛ рд╕реЛрдЪрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдПрдХ рдЫреЛрдЯрд╛ рддрд░реАрдХрд╛ рд▓рд┐рдЦрд╛:
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) {
рд╕рдВрднрд╡рддрдГ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмреБрд░рд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдкрдиреЗ рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде рдореБрдХрд╛рдмрд▓рд╛ рдХрд░рддрд╛ рд╣реИред рдореИрдВ рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреВрдВрдЧрд╛ред
рдирддреАрдЬрддрди, рд╣рдо рдЧреНрд░рд╛рд╣рдХ рдкрд░ рдХреБрдЫ рд╕рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

рдорд╛рдиреНрдпрддрд╛ рдФрд░ рдиреЙрдХрдЖрдЙрдЯ рдЬреЗ.рдПрд╕.
рдПрдХ рдмрд╛рд░ рд╕рддреНрдпрд╛рдкрди рдирд┐рдпрдо рдЬреНрдЮрд╛рдд рд╣реЛ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛрдб рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╡рд┐рдЪрд╛рд░
рдиреЙрдХрдЖрдЙрдЯ рд╕рддреНрдпрд╛рдкрди рд╕реЗ рдЙрдзрд╛рд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдореИрдВ рдЗрд╕ рдкреНрд▓рдЧрдЗрди рдореЗрдВ рд╕рддреНрдпрд╛рдкрди рдирд┐рдпрдо рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛:
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;
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 рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдХрдИ рдЧреБрдгреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИред
рдкреНрд░рдкрддреНрд░ рд╕рддреНрдпрд╛рдкрди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
- рдЬрдм рддрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдлреЙрд░реНрдо рдЬрдорд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХрд░рддрд╛ рддрдм рддрдХ рд╣рдо рдХреБрдЫ рдирд╣реАрдВ рдХрд░рддреЗ
- рдкрд╣рд▓реЗ рдХреЗ рдмрд╛рдж, рдЧреИрд░-рд╡реИрдзрддрд╛ рдХреЗ рдХрд╛рд░рдг рдЕрд╕рдлрд▓, рднреЗрдЬрдирд╛, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдЕрдкрдбреЗрдЯ (рдХреАрдк рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди) рдкрд░ рдлрд╝реАрд▓реНрдбреНрд╕ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред
рдЕрдм рдореИрдВ рдкреВрд░рд╛ рдХреЛрдб рджреВрдВрдЧрд╛, рдФрд░ рдлрд┐рд░ рдореИрдВ рдЗрд╕рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВрдВрдЧрд╛:
ko.validation = new (function () { var isValid = function () { this.validate(true);
рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЛ рддреБрд░рдВрдд рдЬреЛрдбрд╝реЗрдВ:
рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдХрд░рдг
рдХреЛрдб рдХреЛ рд╕реНрдЯреАрдлрди рд╕реНрдЯреЛрдпреЛрдиреЛрд╡ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦрд┐рдд рдПрдХ рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди "рдореЙрдбреНрдпреВрд▓" рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрдкрдиреА рдкреБрд╕реНрддрдХ "рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреИрдЯрд░реНрди" рдореЗрдВ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╛рдиреА рдПрдХ рдЕрдирд╛рдо рддреБрд░рдВрдд рдлрд╝рдВрдХреНрд╢рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рджреЛ рддрд░реАрдХреЛрдВ рд╕реЗ рдПрдХ рд╡рд╕реНрддреБ рд▓реМрдЯрд╛рддрд╛ рд╣реИ: init рдФрд░ addAssertред рдХреНрд▓реЛрдЬрд░ рдХреЗ рдЕрдВрджрд░, рдЖрдЗрд▓рд┐рдб рд╡рд┐рдзрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЕрдорд╛рдиреНрдп рд╡рд┐рдзрд┐ рдореЙрдбрд▓ рд╕рддреНрдпрд╛рдкрди
рдореЙрдбрд▓ рдХреА рд╡реИрдзрддрд╛ рдХреА рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИред рд╡рд┐рдзрд┐ рдХреЛ рдореЙрдбрд▓ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдпрд╣ isValid рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░ рдПрдХ AppViewModel рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдорд╛рдиреНрдп рдореЙрдбрд▓ рдХреА рджреЗрдЦреА рдЧрдИ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╕рд╣реА рдкрд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдлреЙрд░реНрдо рдЬрдорд╛ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рдпрд╛рд╕ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рд╡реИрдз рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╣реА init рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рд░рдВрдн рдХреЗ рджреМрд░рд╛рди рдореЙрдбрд▓ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЕрдЧрд▓рд╛, рд╡рд┐рдзрд┐ рдореЙрдбрд▓ рдХреЗ рд╕рднреА рджреЗрдЦреЗ рдЧрдП рдЧреБрдгреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рддреА рд╣реИ рдФрд░ рдЙрдирдХреА рддреНрд░реБрдЯрд┐ рдЭрдВрдбреЗ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреА рд╣реИред
Init рд╡рд┐рдзрд┐ рд╕рддреНрдпрд╛рдкрди рдкреНрд░рд╛рд░рдВрднрд┐рдХ
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╡рд┐рдзрд┐ рдЙрдкрд░реНрдпреБрдХреНрдд рдорд╛рдиреНрдп рд╕рдВрдкрддреНрддрд┐ рдФрд░ рдКрдкрд░ рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП isValid рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЙрд╕ рдЪрдХреНрд░ рдХреЗ рдмрд╛рдж рдпрд╣ рдЙрди рдХреНрд╖реЗрддреНрд░реЛрдВ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрдВрдз рдЗрдВрдЧрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдирд╛рдо рдХреЗ рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рдЧреБрдг рд╣реЛрддреЗ рд╣реИрдВ, рдореЙрдбрд▓ рдореЗрдВ рдЕрдВрддрд┐рдо рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ: isError рдФрд░ рд╕рдВрджреЗрд╢ред рджреВрд╕рд░рд╛, рдиреЗрд╕реНрдЯреЗрдб рд▓реВрдк рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рдХреЗ рд╕рд╛рде рдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реИред рдПрдХ рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ, рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕рд┐рдореНрдлрдиреА рдХреИрд╢ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдкреНрд░рддрд┐рдмрдВрдз рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдореЙрдбрд▓ (AppViewModel) рдХреЗ рд▓рд┐рдВрдХ рдФрд░ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рд╕рднреА рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЗ рд╕рд╛рдеред
AddAssert рд╡рд┐рдзрд┐ред рдПрдХ рдирдпрд╛ рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдзрд┐ рдХрд╛ рдкрдВрдЬреАрдХрд░рдг
рд╡рд┐рдзрд┐ рддреАрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд▓реЗрддреА рд╣реИ: рдирд╛рдо - рдирдИ рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдзрд┐ рдХрд╛ рдирд╛рдо, рд╕рддреНрдпрд╛рдкрди - рд╕рддреНрдпрд╛рдкрди рд╕рдорд╛рд░реЛрд╣, рдЬрд╛рдБрдЪрдХрд░реНрддрд╛ - рддреНрд░реБрдЯрд┐ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдлрд╝рдВрдХреНрд╢рдиред рд╣рдо рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рдереЛрдбрд╝рд╛ рдмрд╛рдж рдореЗрдВ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред
рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рд╡рд┐рдзрд┐ рдХрд╛ рдирд┐рдХрд╛рдп рдПрдХ рдЕрдиреБрдорд╛рдирд┐рдд рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рд▓рд┐рдкрдЯреЗ рд╣реБрдП рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХреЗ рдХрд┐ AppViewModel.validate рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╕рдордп рд╕рддреНрдпрд╛рдкрди рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛред
CheckAsserts рд╡рд┐рдзрд┐
рдпрд╣ AddAssert рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИред рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХреЛрдИ рдЕрдиреНрдп рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рддреНрд░реБрдЯрд┐ рдХрд░реЗрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рдлрд╝реАрд▓реНрдб рдореЗрдВ рджрд░реНрдЬ рдХреА рдЧрдИ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд▓рдВрдмрд╛рдИ рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╕рдордпред рдпрджрд┐ рдлрд╝реАрд▓реНрдб рдЦрд╛рд▓реА рд╣реИ, рддреЛ рдореИрдВ рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ "рдлрд╝реАрд▓реНрдб рднрд░реЗрдВ", рдФрд░ рдпрджрд┐ рдпрд╣ 3 рд╡рд░реНрдгреЛрдВ рд╕реЗ рдХрдо рд▓рдВрдмрд╛ рд╣реИ - "рдирд╛рдо рдореЗрдВ рдХрдо рд╕реЗ рдХрдо 3 рд╡рд░реНрдг рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП", рдЖрджрд┐ред рд▓реЗрдХрд┐рди рдЗрд╕ рдмрд╛рдд рдХреА рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ рдХрд┐ NotLlank рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╛рдж рдореЗрдВ MinLength рдХреА рдЬрд╛рдВрдЪ рд╣реЛрдЧреАред рдпрд╣рд╛рдБ MinLengt рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдзрд┐ (рдПрдХреНрд╕рдЯреЗрдВрдбрд░) рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:
рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрдк рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдХреНрд░рдо рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рд╕реЙрд░реНрдЯ рдХрд░рддреЗ рд╣реБрдП, рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛рдУрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕рдВрдкрддреНрддрд┐рдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдЙрдирдХреЗ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХреЗ рдХреНрд░рдо рдореЗрдВ рд╣реЛрддреА рд╣реИред рдпрд╣ рдорд╛рдирдХреЛрдВ рдореЗрдВ рдирд╣реАрдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдПрдХ рдХрд╛рдлреА рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдирд┐рдпрдо рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╕рд╡рд╛рд▓ рдЙрдарддрд╛ рд╣реИ рдХрд┐ рдиреЙрдХрдЖрдЙрдЯ рдХреЛ рдЕрдВрджрд░ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП рдФрд░ рдХреНрдпрд╛ рдЕрдЧрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЗрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рддреЛ, рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ рдПрдХ рдмреИрд╕рд╛рдЦреА рдХреА рддрд░рд╣ рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде рд╡рд┐рдХрд▓реНрдк рдореБрдЭреЗ рдЕрдм рддрдХ рдЗрд╖реНрдЯрддрдо рд▓рдЧрддрд╛ рд╣реИред
рдХреЗ рдЙрдкрдпреЛрдЧ
рд╕рддреНрдпрд╛рдкрди рдирд┐рдпрдо рдЙрди рд╕рднреА рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рдЧреБрдгреЛрдВ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рд╡рд░реНрдгрд┐рдд рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд┐рдореНрдлрдиреА рдЗрдХрд╛рдИ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рд╣реА рдлрд╝реАрд▓реНрдб рд╣реИред рддрджрдиреБрд╕рд╛рд░, рдпрджрд┐ рдХрд┐рд╕реА рднреА рдХреНрд╖реЗрддреНрд░ рдХреЛ рдЧреНрд░рд╛рд╣рдХ рдХреА рдУрд░ рд╕реЗ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╕рдорд╛рдзрд╛рди рд╕реНрдкрд╖реНрдЯ рд╣реИ - рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рдирд╛рдо рджреЗрдВ рдпрд╛ рдПрдиреЛрдЯреЗрд╢рди рдкрдврд╝рддреЗ рд╕рдордп рдкреНрд░рд╛рдкреНрдд рдЬреЗрдПрд╕-рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╣рдЯрд╛ рджреЗрдВред
рдХреЛрдбрдкреЗрди рдкрд░ рдПрдХ рдЫреЛрдЯрд╛ рдбреЗрдореЛ рд╣реИ:
codepen.io/alexismaster/pen/LAaqcрдЕрдВрдд рдореЗрдВ, readEntityAnnotations рд╡рд┐рдзрд┐ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд╛ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ред рдЖрдк рд╕рддреНрдпрд╛рдкрди рд╕реЗрд╡рд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдиреЛрдЯреЗрд╢рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
рд╕рдВрджрд░реНрдн:
github.com/Abhoryo/APYJsFormValidationBundle - рд╕рд┐рдореНрдлрдиреА рдмрдВрдбрд▓ рдЬреЗрдПрд╕ рдХреЛрдб рдХреЛ рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рдЬрдирд░реЗрдЯ рдХрд░ рд░рд╣рд╛ рд╣реИ
github.com/Knockout-Contrib/Knockout-Validationhabrahabr.ru/post/136782 - рдиреЙрдХрдЖрдЙрдЯ рдЬреЗрдПрд╕ рдФрд░ рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдкреЛрд╕реНрдЯ
phalcon-docs-ru.readthedocs.org/ru/latest/reference/annotations.html - рдПрдиреЛрдЯреЗрд╢рди рдкрд╛рд░реНрд╕рд░
habrahabr.ru/post/133270 - рд╕рд┐рдореНрдлрдиреА 2 рдореЗрдВ рдХрд╕реНрдЯрдо рдПрдиреЛрдЯреЗрд╢рди