implementing model view view-model in winjs · 2014-05-22 · •the data of the application...
TRANSCRIPT
http://www.interknowlogy.com/
IMPLEMENTING MODEL VIEW VIEW-MODEL IN WINJS
Philip Japikse (@skimedic)
www.skimedic.com/blog
Microsoft MVP, ASPInsider, MCSD, MCDBA, CSM, CSP
Principal Architect, InterKnowlogy
PHIL.TOSTRING()
2
•Principal Architect, InterKnowlogy, Inc.
•http://www.interknowlogy.com
•Microsoft MVP, ASPInsider, MCSD, MCDBA, CSM, CSP
•Founder, Agile Conferences, Inc.
•President, Cincinnati .NET User’s Group
•Co-host, Hallway Conversations
•www.hallwayconversations.com
THE MODEL VIEW VIEW-MODEL PATTERN
3
• The data of the application
• (Can be) Optimized for storage
MODELS
5/22/2014 4
• Accepts Interactions from User
• Returns results of interactions back to
user
VIEWS
5/22/2014 5
• Façade for individual models
• Transport mechanism for models
VIEW MODEL – JOB 1
5/22/2014 6
• Process Incoming requests
• Perform changes to the model
VIEW MODEL – JOB 2
5/22/2014 7
WHY MVVM?
8
DON’T REPEAT YOURSELF
9
SEPARATION OF CONCERNS
10
THE COMMAND PATTERN
11
ENCAPSULATING LOGIC
12
•Wire commands through markup
•markSupportForProcessing
•Check commands through navigation event
•Check Commands on Invocation/Selection
THE COMMAND PATTERN IN ACTION
13
WinJS.Namespace.define("Navigation", { Commands: {
ObservableModelNavButtonClicked: function (e) { WinJS.Navigation.navigate("pages/a_observableModel/ObservableModel.html");
}, }, wireNavigation: function (args) {
WinJS.Utilities.markSupportedForProcessing(Navigation.Commands.ObservableModelNavButtonClicked);
},
});----------------------------------------------------------------------------
<button id="nbcObservableModel"data-win-control="WinJS.UI.AppBarCommand"data-win-options="{
onclick:Navigation.Commands.ObservableModelNavButtonClicked}"></button>
The Command Pattern
14
OBSERVABLES
15
OBSERVABLE MODELS
16
•WinJS.Binding.as
•Classes
•this._initObservable
•WinJS.Class.mix / WinJS.Binding.mixin
•Properties over Fields
USING BINDING.AS
17
/// <reference path="//Microsoft.WinJS.1.0/js/ui.js" />/// <reference path="//Microsoft.WinJS.1.0/js/base.js" />(function () {
“use strict"; WinJS.Namespace.define("ViewModel", WinJS.Binding.as({
contact: {firstName: null,lasName: null,age: null,address: {
number: null,street: null,city: null,
},})
})();
WINJS CLASSES
18
WinJS.Namespace.define("ObservableClassModel", { Contact: WinJS.Class.define(function (firstName, lastName, age) {
this._initObservable(); var self = this; self.firstName = firstName;
}, { firstName: {
set: function (value) {
this.setProperty("firstName", value);}, get: function () {
return this.getProperty("firstName");} },
}),
});
BINDING MIXIN
19
WinJS.Class.mix( ObservableClassModel.Contact, WinJS.Binding.mixin, WinJS.Binding.expandProperties(
ObservableClassModel.Contact));
Observable Models
20
OBSERVABLE COLLECTIONS
21
“use strict"; WinJS.Namespace.define("VM",WinJS.Binding.as({
ContactList :new WinJS.Binding.List(null, {binding:true}),
})
OBSERVABLE CALCULATED VALUES
22
WinJS.Namespace.define("VM", WinJS.Binding.as({ ContactData: {
numberOfContacts: null, }
}));
VM.ContactData.ContactList.bind("length", function (newVal){if (newVal) {
ViewModel.ContactData.numberOfContacts = newVal; }
});
Observable Collections
23
TWO WAY BINDING
24
TWO WAY BINDING
25
WinJS.Namespace.define("Binding.Mode", { twoway: WinJS.Binding.initializer(function (source, sourceProps, dest, destProps) {
//set up normal bindingvar result = WinJS.Binding.defaultBind(source, sourceProps, dest, destProps);
dest.onchange = function () { var d = dest[destProps[0]]; var s = source[sourceProps[0]]; if (s !== d) source[sourceProps[0]] = d;
} })
});
//full code sample at http://www.skimedic.com/blog --------------------------------------------------------------------------------------------------------
<input id="editFirstName" type="text" data-win-bind="value:firstName Binding.Mode.twoway"/>
VALUE CONVERTERS
26
WinJS.Namespace.define("ViewModel.Converters", { defaultIfNull: WinJS.Binding.converter(function (val) {
return val ? val : ""; }), ageCheck: WinJS.Binding.converter(function (val) {
return val && val >= 18 ? “green” : “red”; }),
}); ----------------------------------------------------------
<span style="background-color:white"data-win-bind="style.color:age ViewModel.Converters.ageCheck;
textContent:age ViewModel.Converters.defaultIfNull"></span>
CUSTOM VALUE CONVERTERS
27
WinJS.Namespace.define("ViewModel.Converters", { ageCheck: WinJS.Binding.initializer(
function (source, sourceProps, dest, destProps) { var setColor = function () {
var element = getObject(dest,destProps); var propToChange = destProps[destProps.length - 1]; if (source.age && source.age >= 18) {
element[propToChange]="green"; }else {
element[propToChange] = "red"; }
}; return WinJS.Binding.bind(source, { age: setColor });
}) });
Two Way Binding
28
CONTACT ME
29
•www.skimedic.com/blog
•www.twitter.com/skimedic
•www.hallwayconversations.com
•www.about.me/skimedic