
ViewModel рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП,
рдЧрдВрджрд╛рдлреНрд▓реИрдЧ , рдЬреЛ
рдХреЛрд▓рд╛рдЗрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдиреЙрдХрдЖрдЙрдЯ рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИ:
- рдЧрдВрджреЗрдлреНрд▓реИрдЧ - рд╡реНрдпрдХреНрддрд┐рдЧрдд рдФрд░ рд╕рдордЧреНрд░ ViewModel рджреЛрдиреЛрдВ рдЧреБрдгреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛
- asyncCommand - рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЖрдЬреНрдЮрд╛рдУрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛
- рдЧрддрд┐рд╡рд┐рдзрд┐ - рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ред AsyncCommand рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
рд╡рд┐рд╡рд░рдг
рдиреЙрдХрдЖрдЙрдЯ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкреИрдХреЗрдЬ рдХреЛ рджреЛ рд▓реЛрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛:
рд╣реИрдВрд╕ рдлреЗрдЬрд▓рдорд╛рд░реНрдХ рдФрд░
рдЬреЙрди рдкрд╛рдкрд╛рд╕реНрд░реЛрдд рдХреЛрдб рдФрд░ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВред
ViewModel рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЧрдВрджреЗ рдлрд╝реНрд▓реИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЪрд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд ViewModel рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реЗрддреЗ рд╣реИрдВ:
function Vm(){ var user = { name : ko.observable('Alexey'), email : ko.observable('alexey@mail.me'), address : ko.observable('Moskow st. Petrov 12'), awards : ko.observableArray([new Award('silver','The best speaker'), new Award('gold','Brain Storm #2')]) }, dirtyFlag = ko.DirtyFlag(user); return { user : user, dirtyFlag : dirtyFlag, modelStatus : ko.computed(function(){ return dirtyFlag().isDirty() ? "Changes detected" : "No changes"; }), clearDirty : function(){ dirtyFlag().reset(); } } };
рдпрд╣ ViewModel
dirtyFlag
рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ
user
рд╕рдордЧреНрд░ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдЕрдВрджрд░ рдореВрд▓реНрдпреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЯреНрд░реИрдХ рдХрд░реЗрдЧрд╛ред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рдВрдкрддреНрддрд┐ рдкрд░ рдХрд┐рд╕ рдЯреНрд░реИрдХрд┐рдВрдЧ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рдкрддреНрд░ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
ko.DirtyFlag(user);
ред рдореЙрдбрд▓ рдХреЛ рдмрд╛рдВрдзрдиреЗ рдХреЗ рдмрд╛рдж,
dirtyFlag
user
рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЯреНрд░реИрдХ рдХрд░реЗрдЧрд╛ред рдбреЗрдЯрд╛ рдХреЗ "рдкреНрд░рджреВрд╖рдг" рдХреА рд╕реНрдерд┐рддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ
dirtyFlag().isDirty()
рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░
false
true
рддреЛ
рдбреАрдбреА () true
ред рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХрд┐рдП рдФрд░ рдлрд┐рд░ рдбреЗрдЯрд╛ рдХреЛ рдЕрдкрдиреА рдореВрд▓ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд▓реМрдЯрд╛ рджрд┐рдпрд╛, рддреЛ
рдбреАрдбреАрде рдЭреВрдареЗ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рдП рдЧрдП рдЧреБрдгреЛрдВ рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ (рдпрд╛рдиреА, рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдбреЗрдЯрд╛ рдХреА рдПрдХ рдкреНрд░рддрд┐) рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЖрдк рдЧрдВрджреЗ рдлрд╝реНрд▓реИрдЧ рдХреЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВред
рдиреАрдЪреЗ рдореИрдВ рдкреВрд░реНрдг рдЙрджрд╛рд╣рд░рдг рдХреЛрдб рджреЗрддрд╛ рд╣реВрдВ, рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдЧрдВрджреЗ рдлрд╝реНрд▓реИрдЧ рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
HTML рдЙрджрд╛рд╣рд░рдг рдХреЛрдб <div class ="userform" data-bind="with: user"> <h4>Test user information</h4> <label>Name</label> <input type="text" data-bind="value: name"/> <label>E-mail</label> <input type="text" data-bind="value: email"/> <label>Address</label> <input type="text" data-bind="value: address"/> <div class="awards-title"> <h4>Awards:</h4> </div> <div class="userAwardForm" data-bind="foreach: awards"> <div class="userAwardForm"> <label>Type of award:</label> <input type="text" data-bind="value: awardType"> <label>Name of Contest</label> <input type="text" data-bind="value: contestName"> </div> </div> </div> <div class="dirty-status"> <span>Dirty status: </span><a href="#" data-bind="text: modelStatus(), css: {ok : !dirtyFlag().isDirty(), nok : dirtyFlag().isDirty()}" class="modern"></a> </div> <input type="button" class="Button" value="Reset dirty status" data-bind="click: clearDirty">
рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЙрджрд╛рд╣рд░рдг рдХреЛрдб $(function() { function Award(atp, contestNamev){ var awardType = ko.observable(atp), contestName = ko.observable(contestNamev); return { awardType : awardType, contestName : contestName } } function Vm(){ var user = { name : ko.observable('Alexey'), email : ko.observable('alexey@mail.me'), address : ko.observable('Moskow st. Petrov 12'), awards : ko.observableArray([new Award('silver','The best speaker'), new Award('gold','Brain Storm #2')]) }, dirtyFlag = ko.DirtyFlag(user); return { user : user, dirtyFlag : dirtyFlag, modelStatus : ko.computed(function(){ return dirtyFlag().isDirty() ? "Changes detected" : "No changes"; }), clearDirty : function(){ dirtyFlag().reset(); } } }; ko.applyBindings(new Vm()); });тАЛ
рд╕реАрдПрд╕рдПрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛрдб body{ background-color: #456192 ; margin:20px; } label{ display:block; color: white; } div.userform, div.userAwardForm{ padding: 10px; border: solid white 1px; } div.userAwardForm{ margin-top: 10px; } div.userform h4{ font-weight : bold; font-size:24px; margin-bottom: 15px; color: white; } .awards-title{ margin-top:10px; } .modern { height: 40px; padding: 0 5px; line-height: 40px; font-size: 14px; font-weight: bold; color: white; text-shadow: -1px -1px 0 #333; border-radius: 3px; text-decoration:none; } .ok{ background: -moz-linear-gradient(#84AB69, #334823); background: -webkit-linear-gradient(#84AB69, #334823); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#84AB69', endColorstr='#334823')"; } .nok{ background: -moz-linear-gradient(#ED3812, #7A1F05); background: -webkit-linear-gradient(#ED3812, #7A1F05); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#ED3812', endColorstr='#7A1F05')"; } .dirty-status{ height: 50px; } .dirty-status span{ color: white; } .Button { position: relative; cursor: pointer; display: inline-block; border: 1px solid #d5d5d5; text-decoration: none; font: 16px Arial; font-weight: bold; text-align: center; text-shadow:0px 0px 0px #444444; background: #ffffff; padding: 10px 16px; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; color: #c13737; -moz-box-shadow:inset 0px 0px 0px; -webkit-box-shadow:inset 0px 0px 0px; box-shadow:inset 0px 0px 0px, 0 3px 0 #aeaeae, 0 5px 0 #c13737, 0 8px 0 #aeaeae, 0 10px 6px rgba(0,0,0, .60); } .Button:hover { background: #eeeeee; color: #eb5e7f; -moz-box-shadow:inset 0px 0px 0px; -webkit-box-shadow:inset 0px 0px 0px; box-shadow:inset 0px 0px 0px , 0 3px 0 rgba(235,94,127, .30), 0 3px 0 #aeaeae, 0 5px 5px #eb5e7f, 0 5px 0 #eb5e7f, 0 8px 0 rgba(235,94,127, .15), 0 8px 0 #aeaeae, 0 10px 6px rgba(0,0,0, .60); } .Button:active { transform: translateY(2px); -moz-transform: translateY(2px); -ms-transform: translateY(2px); -o-transform: translateY(2px); -webkit-transform: translateY(2px); -moz-box-shadow:inset 0px 0px 0px; -webkit-box-shadow:inset 0px 0px 0px; box-shadow:inset 0px 0px 0px, 0 3px 0 rgba(235,94,127, .30), 0 3px 0 #eeeeee, 0 5px 5px rgba(#eb5e7f, .65), 0 5px 0 #eb5e7f, 0 6px 0 rgba(235,94,127, .15), 0 6px 0 #eeeeee, 0 6px 6px rgba(0,0,0, .65); }
рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдПрдХ рд╕рдВрдХреЗрдд рдХреЗ рд░реВрдк рдореЗрдВ, рд╢рд┐рд▓рд╛рд▓реЗрдЦ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ: "рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ" - рдпрджрд┐ рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ "рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдкрддрд╛ рдЪрд▓рд╛" - рдпрджрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдкрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдФрд░ рдПрдХ рдкреГрд╖реНрдарднреВрдорд┐ рдкрд░рд┐рд╡рд░реНрддрди рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╕рдВрдХреЗрдд рдХреЗ рд▓рд┐рдП рд╢рд┐рд▓рд╛рд▓реЗрдЦ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
"рд░реАрд╕реЗрдЯ рдбрд░реНрдЯреА рд╕реНрдЯреЗрдЯрд╕" рдмрдЯрди рдЙрджрд╛рд╣рд░рдг рдлреЙрд░реНрдо рдкрд░ рд╕реНрдерд┐рдд рд╣реИ, рдЬреЛ
рдЧрдВрджреЗ рдлрд╝реНрд▓реИрдЧ рд╡реНрдпреВрдореЙрдбрд▓ рдкреНрд░реЙрдкрд░реНрдЯреА рдХреЗ
reset
рд╡рд┐рдзрд┐ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╡рд░реНрддрдорд╛рди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдмреБрдирд┐рдпрд╛рджреА рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдП рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ
dirtyFlag().reset();
рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
dirtyFlag().reset();
ред
рдирд┐рд╖реНрдХрд░реНрд╖
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд▓рд╛рдЗрдмреНрд░реЗрд░реА ViewModel рдХреЗ рдЖрд╡рд╢реНрдпрдХ рдЧреБрдгреЛрдВ рдкрд░ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧреАред
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!
рдкреБрдирд╢реНрдЪ рдореИрдВ рдЦреБрдж рдХреЗ рд▓рд┐рдП рддрд╕реНрд╡реАрд░ рдЖрдХрд░реНрд╖рд┐рдд рдХрд┐рдпрд╛ :)