рдиреЙрдХрдЖрдЙрдЯ рдЬреЗрдПрд╕: рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдпрд╛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдХрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИ

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

рдЖрдЬ рдореИрдВ рдпрд╣ рдЬрд╛рдирдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкреНрд░реЗрдХреНрд╖рдгреЛрдВ рдФрд░ рд╕рдВрдкреВрд░реНрдг рджреГрд╢реНрдп рдореЙрдбрд▓реЛрдВ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдФрд░ рд░реЛрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреЙрдХрдЖрдЙрдЯ рдЬреЗрдПрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВред

рдиреЙрдХрдЖрдЙрдЯ рдЬреЗрдПрд╕ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдЪрд┐рдд рддреБрд░рдВрдд рд╡рд┐рд╖рдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреЗ рдмреНрд▓реЙрдЧ рдХреЗ рд▓рд┐рдП рджреЛ рд▓рд┐рдВрдХ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ

рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдлрд╛рдпрджреЗ рдФрд░ рдХрд╛рдлреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдиреБрдХрд╕рд╛рди рджреЛрдиреЛрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдХрдордЬреЛрд░рд┐рдпрд╛рдБ

рдареАрдХ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡реЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЕрд╡рд▓реЛрдХрди рдХрд░рдиреЗ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХрдИ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

рдХрдЯреМрддреА рдХреЗ рддрд╣рдд, рд╣рдо рдПрдХ рд╕рд░рд▓ рддрдВрддреНрд░ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ рдЬреЛ рд╕рд░рд▓ рдФрд░ рдкрд╛рд░рджрд░реНрд╢реА рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдЕрдкрдирд╛рдиреЗ рдФрд░ рд░рджреНрдж рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛ред



рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдпрд╛ рд░рджреНрдж рдХрд░рдиреЗ рдХреА рдмрд╛рдд рдЖрдиреЗ рдкрд░ рдореЗрд░реЗ рджрд┐рдорд╛рдЧ рдореЗрдВ рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдбреАрдмреАрдПрдордПрд╕ рдореЗрдВ рд▓реЗрдирджреЗрди рдФрд░ рдЙрдирдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рд▓реЗрдирджреЗрди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдХрдорд┐рдЯ рдпрд╛ рд░реЛрд▓рдмреИрдХ рдХрд░реЗрдВред рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИред

рд╡реЗрдзрд╢рд╛рд▓рд╛рдУрдВ рдореЗрдВ рдЗрди рддрд░реАрдХреЛрдВ рдХрд╛ рдПрдХ рдПрдирд╛рд▓реЙрдЧ рдмрдирд╛рдиреЗ рд╕реЗ рд╣рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рд░реЛрдХрддрд╛ рд╣реИред рдЖрдк рдмрд╕ рдХрд╛рд░реНрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╛рджреГрд╢реНрдп рджреНрд╡рд╛рд░рд╛ рдЕрдкрдиреЗ ko.transactionableObservable рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 ko.transactionableObservable = function(initialValue) { var result = ko.observable(initialValue); result.beginTransaction = function() { ... }; result.commit = function() { ... }; result.rollback = function() { ... }; return result; } var name = ko.transactionableObservable('habrauser'); 


рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рджреГрдврд╝рддрд╛ рд╕реЗ рдирд╛рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд░рд┐рдгрд╛рдо рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рд╣реИред рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЕрдЧрд░ рд╣рдо рдПрдХ рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдп рдпрд╛ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ / рд░рджреНрдж рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдкреНрд░рд╕реНрддреЛрддрд╛ , рдЬреЛ рдиреЙрдХрдЖрдЙрдЯ рдХреЗ рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдП, рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддреЗ рд╣реИрдВред

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

 var name = ko.observable('habrauser').extend({editable: true}); 


рдХреБрд░реВрдкрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрдбрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рд░рд▓ рд╣реИ:
ko.extenders['myExtender'] = function(observavle, params){}

рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдореЗрд░реЗ рд▓рд┐рдП рд╕рд╛рд░реНрдердХ рд▓рдЧрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдЗрдП рдЕрдкрдиреЗ рд╡рд┐рд╕реНрддрд╛рд░рдХ рдХрд╛ рдПрдХ рд╕рд░рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд░реЗрдВ

 ko.extenders['editable'] = function (target) { var oldValue; var inTransaction = false; target.beginEdit = function () { var currentValue = target(); if (currentValue instanceof Array) { currentValue = currentValue.slice(); // make copy } oldValue = currentValue; inTransaction = true; }; target.commit = function () { inTransaction = false; }; target.rollback = function () { if (inTransaction) { target(oldValue); inTransaction = false; } }; return target; }; 


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

рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг:
 var name = ko.observable().extend({editable: true}); var nameLength = ko.dependentObservable(function() { return name() ? name().length : 0; }); name('user'); // name set to 'user' name.beginEdit(); // begin transaciton name('me'); // name set to 'me', nameLength was recalculated nameLength(); // gives us 2 name.commit(); // transaction commited; values are unchanged since last edit; we could start another one name.rollback(); // nothing happens since transation is commited name.beginEdit(); // begin another transaction name('someone'); // name set to 'someone', nameLength was recalculated name.rollback(); // rollback transaction; name set to initial value 'me', nameLength recalculated name(); // returns 'me' 


рдЭрдВрдбрд╛, рдмрджрд▓рд╛рд╡ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣реЛрдирд╛ рднреА рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред рд╕рд┐рджреНрдзрд╛рдВрдд рд╕рд░рд▓ рд╣реИ:
 target.hasChanges = ko.dependedObservable(function () { var hasChanges = inTransaction && oldValue != target(); return hasChanges; }); 


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

рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣рдореЗрд╢рд╛ рдЧрд▓рдд рд╣реЛрдЧрд╛ред рдФрд░ рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рд╣реИ: рдкрд╣рд▓реЗ рдирд┐рд╖реНрдкрд╛рджрди рдореЗрдВ (рдпрд╛рдиреА рдШреЛрд╖рдгрд╛ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж) InTransaction == рдЧрд▓рдд, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ AND рдСрдкрд░реЗрдЯрд░ рдХреА рджреВрд╕рд░реА рдЬрд╛рдВрдЪ рднреА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХреА рдЬрд╛рдПрдЧреАред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ dependendObservable рдХрднреА рдкреБрдирд░реНрдЧрдгрдирд╛ рдирд╣реАрдВ рд╣реЛрдЧреАред рдЗрд╕реЗ рдареАрдХ рдХрд░рдирд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рд╣рдо inTransaction рдЪрд░ "рдЕрд╡рд▓реЛрдХрдиреАрдп" рдмрдирд╛рддреЗ рд╣реИрдВред

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд▓реЗрди-рджреЗрди рд╕реЗ рдкреНрд░рд╡реЗрд╢ / рдирд┐рдХрд╛рд╕ рдкрд░ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рдПрдЧреА рдФрд░ рдЬрдм рдореВрд▓ рдЕрд╡рд▓реЛрдХрди рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдП!

 ko.extenders['editable'] = function (target) { var oldValue; var inTransaction = ko.observable(false); target.beginEdit = function () { var currentValue = target(); if (currentValue instanceof Array) { currentValue = currentValue.slice(); // make copy } oldValue = currentValue; inTransaction(true); }; target.commit = function () { inTransaction(false); }; target.rollback = function () { if (inTransaction()) { target(oldValue); } }; target.hasChanges = deferredDependentObservable(function () { var hasChanges = inTransaction() && oldValue != target(); return hasChanges; }); return target; }; 


рдореЗрд░реЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдареЛрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдорд┐рд▓рд╛ред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рджрд░реНрдЬрди рдЦреЗрдд рд╣реИрдВред рд╕рдВрдкрд╛рджрди рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╢реБрд░реВ () рдФрд░ рдлрд┐рд░ рдХрдорд┐рдЯ / рд░реЛрд▓рдмреИрдХ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдк рдЦреБрдж рдХреЛ рд▓рдЯрдХрд╛ рд╕рдХрддреЗ рд╣реИрдВред

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

 var user = { firstName : ko.observable('habrauser'), lastName: ko.observable('sapiens') }; user.fullName = ko.dependentObservable(function() { return user.firstName() + ' ' + user.lastName(); }); ko.editable(user); user.beginEdit(); user.firstName('homo'); user.fullName(); // 'homo sapiens' user.hasChanges(); // true user.commit(); 


рдпрджрд┐ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдордиреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЕрд╡рд▓реЛрдХрди рд▓реЗрди-рджреЗрди рдХрд┐рдпрд╛, рддреЛ рдЕрдм рд╣рдо рдПрдХ рдордирдорд╛рдирд╛ рд╡рд╕реНрддреБ рд▓реЗрди-рджреЗрди рдХрд░ рд░рд╣реЗ рд╣реИрдВред рджреНрд╡рд╛рд░рд╛ рдФрд░ рдмрдбрд╝реЗ, рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓рддрд╛ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
 ko.editable = function (viewModel, autoInit) { var editables = ko.observableArray(); (function makeEditable(rootObject) { for (var propertyName in rootObject) { var property = rootObject[propertyName]; if (ko.isWriteableObservable(property)) { var observable = property; observable.extend({ editable: true }); editables.push(observable); } property = ko.utils.unwrapObservable(property); if (typeof (property) == 'object') { makeEditable(property); } } })(viewModel); viewModel.beginEdit = function () { ko.utils.arrayForEach(editables(), function (obj) { obj.beginEdit(); }); }; viewModel.commit = function () { ko.utils.arrayForEach(editables(), function (obj) { obj.commit(); }); }; viewModel.rollback = function () { ko.utils.arrayForEach(editables(), function (obj) { obj.rollback(); }); }; viewModel.addEditable = function (editable) { editables.push(editable.extend({ editable: true })); }; viewModel.hasChanges = deferredDependentObservable(function () { var editableWithChanges = ko.utils.arrayFirst(editables(), function (editable) { return editable.hasChanges(); }); return editableWithChanges != null; }); }; 


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

рдФрд░ рдПрдХ рд╕рд░рд▓ рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг:

 var user = { FirstName: ko.observable('Some'), LastName: ko.observable('Person'), Address: { Country: ko.observable('USA'), City: ko.observable('Washington') } }; ko.editable(user); user.beginEdit(); user.FirstName('MyName'); user.hasChanges(); // returns `true` user.commit(); user.hasChanges(); // returns `false` user.Address.Country('Ukraine'); user.hasChanges(); // returns `true` user.rollback(); user.Address.Country(); // returns 'USA' 


рд╣рдорд╛рд░реЗ рд╢реЛрдз рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдореЗрдВ рдЙрддреНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЛрдб рддреИрдпрд╛рд░ рдорд┐рд▓рд╛, рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ GitHub рдкрд░ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдФрд░ ko.editables рдирд╛рдо рджрд┐рдпрд╛: github.com/romanych/ko.editables

рд╕рд░рд▓ рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдФрд░ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИрдВ ред

рдЕрдВрдд рддрдХ рдкрдврд╝рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдХреЛ рдзрдиреНрдпрд╡рд╛рджред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдХреЛрдб рдХрд╛рдо рдЖрдПрдЧрд╛ред

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


All Articles