1

advertisement
1
>> Jeremy Foster: So we're going to be talking about JavaScript tonight. How
many people are C-Sharp, totally C-Sharp? That's what I thought. A lot of
people are. I totally came from C-Sharp. JavaScript was always kind of
love/hate, mostly hate. I jumped into Windows 8 and for some rope, I went to
JavaScript way. I actually remember after being in this role for a couple
months, calling a colleague and being like, I need out. I've got to get back
to C-Sharp, because I feel really, really bad here, you know.
This is not a happy world. JavaScript just leaves me out in the woods and the
dark so often, and it's just not fun. But he told me to stay in it, and I
stayed in it, and now I'm really happy. I'm really loving the JavaScript
stuff. It's really cool. And the tools are getting better, and the
performance is getting better. Not that it was ever really bad, but just the
performance measurements, monitoring and stuff, is getting better.
It's really a cool world to be in. It's kind of amazing being on the client
and writing this JavaScript. So we're going to be talking about all JavaScript
tonight.
Who here is a JavaScript head or a web platform person?
>>:
I've done both.
>> Jeremy Foster: All right. So if I am talking to mostly a crowd of C-Sharp
developers, I assume that you guys would maybe enjoy the occasional, this is
the equivalent in C-Sharp of, that type of thing? Great.
So there are kind of two components to the presentation tonight. First is the
app itself. This is called Code Show, and I use this though show HTML and
JavaScript programming in Windows 8. And the app itself I made in the -- so I
can show kind of the architecture of the app and how it actually works and
builds the tiles and looks at metadata and stuff like that.
And I don't know, I'll try to think about whether that would be more helpful.
Or the second tier is actually taking you through the demos themselves and
showing you how these things are done.
2
Now, if you're just looking to see how to do certain Windows 8 things, a lot of
the things that happen in here end up calling into the Win RT API, and that's
the way it's done, and it's the same way pretty much the exact same way in both
JavaScript and C-Sharp. So you'll still kind of, you know, learn how to, for
instance, tie up to a sensor or integrate with Bing maps or whatever, whether
you do it in JavaScript or in C-Sharp.
But I'll go ahead and start with the overall app architecture and then I'll
move into a few of these demos. I'll look at whichever ones I think might be
the most helpful for you. And then you guys can feel free, if you see one
blaze by and I don't hit on it, I'll leave plenty of time for Q and A, and when
we get to that point, you'll say can you show me this one. I've always wanted
to know how to make a custom control in JavaScript, or I've always been looking
to use the flip view control in JavaScript or something like that and I'd be
glad to show a demo.
By the way, Code Show is a project that I, of course, I put it in the store for
free. I have an ad in there mostly for just display. I make like two dollars
a month on it. But I have it on codeplex, and when I put it on codeplex, I
said, well, let's do this in TFS, you know, and so I put it in TFS on codeplex,
and when I was trying to tell people to collaborate, I thought that they were
going to be able to go into codeplex and connect to that source control so that
they could always just do get, get latest version, and pull it into visual
studio.
And I ended up hearing from somebody in the field saying, no, we're not able to
do that. Apparently, I would have had to grant them as a contributor with
their codeplex ID, and then that's the only way that -- I mean, I kind of knew
that they would have to do that if they were going to contribute to it, but
they would even have to do it if they were going to consume it, if they were
just going to get latest version.
So does anybody have any experience with that?
>>:
Yeah, you have to download --
>> Jeremy Foster: You've run into the same thing, yeah. So you have to
download the static file. Code Show changes quite a bit. We add demos to it.
We've got a couple contributors to it, and so I wanted people to be able to
feel like they kind of had a live connection to it so they don't have to go
3
seeking out the latest version.
>>:
Why didn't you just --
>> Jeremy Foster: So I didn't want to use Get Hub, because Get Hub is a direct
competitor. And I know a number of people are using Get Hub, but I was like
I'm going to stick to the party line here. And then we started allowing Get
source control in codeplex. How many people knew that?
>>:
From last time.
>> Jeremy Foster: From last time? How many people have used GET as a source
control in codeplex? How many people have used GET at all? Handful of you,
okay. What are your impressions with GET compared to TFS? I'm talking just
about the source control, not about the overall ALM.
>>:
It is the best source control ever.
>> Jeremy Foster:
Stated simply.
>>: I haven't figured out integrating Visual Studio, like the TFS version was
just automatic.
>> Jeremy Foster:
>>:
Yeah.
I have a GET project that I have to use different tools.
>> Jeremy Foster:
Seems to work.
Anyone else?
>>: Is the one on codeplex or whatever, I went to TFS.visualstudio.com to
access my project. Does the GET there integrate Visual Studio?
>> Jeremy Foster: They both do. Any GET project will integrate in Visual
Studio and I'll show you how that works.
>>:
Okay.
That would be cool.
>> Jeremy Foster: Okay. The reason why I want very much to show you why this
works is this. Primarily, I have two people, myself and one other, that have
contributed to Code Show. I would like very much to have more contributors to
4
Code Show, and I want you guys to see how it's done, because it's super, super
simple. It's just the creation of an HTML, a CSS and a JavaScript file that
does whatever you want to show off, and you just add a little bit of meta
information in the HTML file and you contribute that, a folder with those three
files in it, and that's it. It will automatically show up as a tile on the
front screen and it will automatically work that demo.
And so I want people to contribute to it, and whether you're doing JavaScript
or C-Sharp, hopefully this will help. So if I go to my Visual Studio instance,
which mine is codefoster.visualstudio.com, this is all the projects that I have
in my TFS, my -- this is the service, not Terminal Foundation Server, but
service. This is all the projects that I have and these can be private. So
this is the equivalent of the pay version of Get Hub, really, okay? These can
be private.
And so I can restrict these to only the people that I've elected to be on my
team. So I can build a little team and as long as my team is five or less,
it's free, at least for now. It says that -- doesn't say it here, but when
you're not logged in, when you're on kind of the public landing page, it talks
about how there's going to be a free tier. But for now, everything's free in
it, because it's just spinning up.
But this is really cool, that I've actually got a little game group. I call us
the UnderGround App Dev group, and there's three of us, and I just give them
accounts in here with their live IDs. One of them has a Gmail account and one
has some custom account, but they're all on here as contributors to my project.
So that's really cool. When you /KRAEBGT a new project, you can create a
project using GET, and now you get all of the glory that is TFS. I mean TFS is
amazing. I don't even really see any direct competitors to TFS. It's just
awesome.
You get all the glory that is TFS, but your repository is sitting on top of Get
Hub, and so that's really beautiful. So now I can go to my app. This is one
of my projects that is in training set, but it's setting on top of Get Hub, and
I can go to the code tab. This is in TFS now, not codeplex, although codeplex
is sitting on top of TFS, they work a little bit differently.
So now here's little pond, and I can go over here. It's a little obscure. I
think this needs to be a little more clear, but this icon on the far right is
clone. And if I click on that, it gives me the GET command and the URL to
5
clone this Get Hub repository. And now, anybody in the whole world, doesn't
matter if they have an account on TFS, they don't have to have anything TFS,
anything Microsoft specific, nothing installed. They just have to have GET
installed on their computer.
They can type in Get Clone and that URL, and it will automatically create a
folder and put this entire project inside that folder on their machine. Plus,
because you did a clone action, that clone will set up this URL as a remote.
And a remote is like a repository that I'm aware of, okay. So they're going to
be working on their machine. They'll make changes, commit to the repository on
their machine, make some more changes, make another commit, continue to work
locally as much as they want, and as soon as they have something that they
like, like some commits that they think add some value to the project, if they
are a team member on this project, if they're one of my guys, then they can do
what's called a push to that repository, and it will push those commits, those
changes that they made up to that repository.
You actually have to go up to your profile in TFS and create a flat ID and
password, because otherwise you're logged in as your live account, and you
don't want to log in through the GET terminal with your live account. The so
you go in and create yourself flat credentials. I'll show you that real quick.
I go into my profile, my profile, and the credentials tab allows me to go
change this secondary credential. So I go set it to whatever password I want,
and now that's my kind of flat credential for accessing that repository.
So this is really neat, because somebody can really easily do a Get Clone and
then all they have to do is do Get Pull and it pulls down from this repository,
pulls down all the latest commits. So anything that the people who own the
project have pushed into it, they hit pull and it refreshes it. It's just like
a Get Latest version.
It pulls all that, merges it in their project automatically and they've got the
latest. And they never had to sign up for anything, they never had to do
anything. So that's really helpful for people.
Now this all exists in the form of codeplex at codeplex, and if you go to
codeshow@codeplex.com, like I said when I started Code Show, I had this hosted
in TFS on codeplex. But at one point, I realized I want to open this up for
more contributions and so I want to host this on GET. And so I went into the
6
source control and I tried to change it to GET and it said in order to change
it, you have to email this person. Well, that's a fun work flow in 2013.
So I emailed this person, and man they got back to me like the next day and
said all right, it's converted. I was like really? I came and logged back in
and all of a sudden, it looks like this, you know. I've got GET verbiage all
over the place. And I am absolutely loving the way this works now, because I
still get -- since codeplex is still sitting on top of TFS, it still takes
advantage of all the things like work items and all of the other ALM features
that TFS gives us. And yet, for my repository, I've got a get repository.
This one, I think, looks a little bit better. It's a little bit more clear
that I can clone by doing this. And the clone address for Code Show is just
that so I can give that to anybody I want in any form. I can just say here's
my repository URL. They can do Get Clone, they've got my whole project, okay?
Now, if they want to clone it and pull any time they want, they can always pull
changes. They can always get the latest version of Code Show, no problem. But
if they want to push, they're going to have to have a codeplex account. I'm
going to have to know who they are if they're going to push into codeplex,
right.
So how do I allow just any Joe to contribute to codeplex?
the answer?
>>:
Submit a patch.
>> Jeremy Foster: Submit a patch.
GET terminology, what do they do?
>>:
Does anybody know
That's not in GET terminology, though.
In
[indiscernible].
>> Jeremy Foster: They fork and they do a pull request. Okay? It's actually
easier than it sounds. I don't know why the terminology has to sound so
arcane, but the first thing they do is they say, you know what? I'm interested
in this project, and I've already cloned it, and I've already, you know, pulled
it a few times, got the latest and I've written some stuff on it. But I want
to contribute these.
So they hit fork, and what happens then is fork requires that they have a
7
codeplex account, because forking takes a public repository, like Code Show, it
takes a project and says, you want to duplicate that project in your own
codeplex account. And so now there's a mirror image of Code Show that they are
hosting, and that's the key. It has to be another publicly hosted repository.
So they've just forked it, but their fork has an awareness of the real Code
Show, the original project, and so they can, from that, they can, you know,
maintain that live link. And then they can make the changes on their local
computer, and then they can push into their fork. And then once they've pushed
some commits into their fork on their repository, then they can come here and
it probably won't -- oh, it will let -- no, for me, since I'm the owner of
this, it's only telling me how many people have done a pull request, which
right now is a grand zero. Two people have forked the project, but zero people
have done a pull request.
But somebody that doesn't own Code Show would come in here and they would look
at this, and they would see the option to submit a pull request, and they would
choose which -- they would, you know, they would give them their fork and they
would choose the commits and they would say boom, go. What that does is it
sends a message to me that says Joe just forked your project, made some
changes, and submitted a pull request. Here are his changes and it will show
you all of the deltas on all the files, whether it's XAML or a CS file or a JS
file or whatever. It will show you all of those deltas. So you can see
exactly what he did.
If you want you, can pull that down to local and run it and go yeah, that's
really good. I don't see any bugs in their code. I think it's a value added
to the project so I going to go ahead and pull that. That's why it's called a
pull request, because he's requesting that I pull his changes into my project.
So he does that pull request. I say that's good. I pull it in. It
automatically merges all of his changes into my project and now I've got it,
okay? So that's the procedure for that.
It's nice because Joe can be anybody using whatever system. I don't care what
IDE he uses. I don't care if he's using notepad or whatever, and he doesn't
have to have any of the credentials unless he's actually going to fork, and
then all he needs is his own account. It doesn't have to be a contributor in
the Code Show project.
8
So hopefully, that's helpful now. If you are used to that work flow of using
your source control inside of Visual Studio, then what you want to do is
upgrade Visual Studio to update to CTP. Have you guys heard of update to CTP?
So this, rolled out with the GET changes, there's Visual Studio, and then
there's update one. You probably all got it. And then there's update two,
CTP, which is not being pushed since it's CTP, but you can go grab that change.
I haven't had any issues with it. You can go grab update to CTP, and then you
can install the -- wait for it -- you can install the Visual Studio tools for
GET, which this just revved up to version point 8 just now, and I just
installed it. Visual Studio tools for GET. Don't be confused, because there's
been a source -- a GET plug-in for Visual Studio for some time. It was called
get Source Control For Visual Studio or something like that.
That's the version that looks at the GET binaries on your computer, the actual
GET program, and it makes it work in Visual Studio. But this version actually
upgrades all of the ALM and everything inside of Visual Studio. So you can
look at repositories, look at all the commits on them and everything.
So I've got this, so let me try -- I don't usually work in Visual Studio, as
you might notice by my fumbling, but I can go look at Team Explorer here and I
can connect to -- oh, I wonder if it's because I just created this. But
anyway, I can connect to a GET repository and it gives me all kind of -- I can
see all the diffs right in Visual Studio. I can see the commits, the basically
the changes. I can see a big history of all the changes. I'm waiting for it
to integrate a visual, like a branch -- like a visual branching representation,
because those are really cool with GET. GET's like incredible with branching
so it's really nice to be able to see all your commit branches and stuff.
And I don't think it's in that plug-in.
be really nice.
>>:
Can you start [indiscernible].
>> Jeremy Foster:
>>:
I haven't found it yet, but that would
And then you can visualize?
And it can be basically used to [indiscernible].
>> Jeremy Foster: Now, I don't use any of those. I used to use my source
control in Visual Studio all the time, and I tried doing that with GET, and it
just felt a little more awkward. I got used to the GET commands finally. I
9
don't know what that makes me, but now I good to Get Shell. The easiest way to
get Get Shell on your computer is to just small Get Hub for Windows. If you
install Get Hub for Windows, it does it really nicely, it installs this Get
Shell, which is basically Posh Get. That's the PowerShell GET. Now, you have
Posh Get on your computer. You can run it, and you can use PowerShell and
access all your GET commands.
And if you're a command line person, you're going to absolutely love this. If
you just hate the command line, it has to be gooey for you, you're going to
hate this. So definitely get that plug-in for Visual Studio.
But now I get in here, and the thing I love about GET is that the repository
travels with the folder. So it doesn't really matter where on my computer I
put my development projects. The repository's right there inside of them in a
hidden dot-GET folder. So it's all there.
So I've got this development folder, and I can go into -- I've got my construct
two games and I can go into that fish game, the little pond. And as soon as I
move into a fold their has a hidden GET folder in it, it says hey, I notice
that this is a GET repository. So it shows me the branch that I'm currently
on.
So now I can use my GET commands, like I can use Get Status and it going to
show me what's different between my working folder and this GET repository, and
it says there's nothing to commit. Your working folder is clean. Let me add
something here. Let me add hello world, and let me add that to a text called
HW.TXT. Is everybody familiar with that piping command? I'm just taking a
string and writing it into a file. So I just created a file.
And now my GET indicator is saying there's been a file added, that little plus
one means there an addition, and if I do a Get Status now, it says here's a
file that I recognize, but this is an untracked file. GET wasn't aware of this
file before, and we're not, by default, going to assume that you want that even
as part of your repository. So I can go, for instance, I can do get, add
hw.txt or oftentimes, if you've got a lot of things to add, you do get add dot.
And it adds that into there, and now when I do a Get Status, it says you have a
staged change. This new file, hw.txt is /STAEUPLGed to be added to that
project.
Then I can do a Get Commit, and it opens up notepad for me, and I can write all
10
the notes that I want about what that commit was. Just a hello world test
commit. Okay? All the rest of that is going to just be comments. So it's not
actually going to show up in my commit text. And then when I close notepad and
save change, GET uses that as that last commit and now I can do Get Log and it
will show me all my commits. That's a little bit hairy, so I do Get Log one
line. That needs two dashes. Get Log One Line and now I can see the complete
history of that repository.
Notice, I'm just looking on my local computer right now, and the last one is
just a hello world test commit. I just committed that change right there. And
now I can push this up to the server like this. So I have an awareness if I
type get remote, it shows me everybody I have an awareness of, and I've named
it TFS. So I have this short cut in GET called TFS. And actually if I do get
remote V, for verbose, it says TFS, and it's pointing to that URL. It shows it
twice because, you know, there's a different one for the fetching versus the
pushing.
But in most cases, they're the same URL, at least for TFS it always is.
So now I can do get push TFS my master branch bam. And it's going to look at
that remote, TFS, and it going to look at what commits that I have locally that
it doesn't have, and it's going to public that commit up to TFS.
Same thing would work in codeplex. This might take a while, because if you
don't know, a commit is actually a snapshot of the entire repository. But GET
is super smart about never duplicating information. So if you have a file in
there twice, it actually is being intelligent about the way that it stores it.
So it doesn't -- it's actually -- the repositories are surprisingly small.
Surprisingly small, especially when you've got -- since you've got so many
version. And now it's copied that whole thing up and I just added that commit
up into my repository, all right?
I think this is the way we're going. I think that the TFS team indicates that
with adding support for GET into the TFS solution. So that's pretty cool. Any
questions on that?
All right. Let's go ahead and open Code Show. So again, you get the source
control real easily by just doing a get poll or you can go into the source code
and download a zip file of the whole thing. And Code Show is currently a few
little projects, but that's -- these are just components for one of the demos
11
so we can show off what components are.
testing suite.
And then this is the start of a
Is anybody kind of an expert in C-Sharp unit tests? Decent? We're all kind of
quasi experts in it. We should all be better, right? We should all be better
citizens and be better at our unit test? Well, when I jumped into the
JavaScript world, I thought how in the world am I going to do my unit test?
Because unit tests don't integrate with Visual Studio like they do in C-Sharp.
And I found my answer in another project called Hilo JS, that the patterns and
practices group works on. And it's really helpful. It's a really
well-designed app that's really a simple scope, really low scope app, it's like
a picture app for Windows 8. But they did it really, really right.
>>:
Where is the link?
>> Jeremy Foster: It's Hilo JS, H-i-l-o, and you can find it in the MSDN
samples. You can also find it at, I think it's at hilojs.codeplex.com. So
hilojs.codeplex.com. That's it. And it's hosted in GET. So if you jump over
to the source code, and then click on clone, you'll see the clone URL for
getting Hilo JS. Now Hilo JS is a project, and then a test project, and the
way that I learned from that app that this works is here I've goat code show my
main project, right. And then I've got this test project. And notice I've got
Code Show in there with a little "X" on it.
The way this is working is this is a linked reference to another project, and
in order to add a file as a linked reference, I actually didn't even know that
you could do this. I had never in all my years of programming done this
before. You can actually, when you add a reference or add a file to the
project, you can say I want to add it as a link, and then it keeps that file in
its original location. I don't know why I never ran into that.
Anyway, it turns out if you want to do that for an entire folder and kind of
automatically get all of its contents recursively, you can go into the project
file, into the XAML, and you can add a little content line in there and
reference that folder.
So if you want to see how that's done, just look in the project file for my
test project, and you'll see exactly how I dragged -- actually, I'll just go
ahead and show that. I'll take my test project, and I'll unload it, and then
12
I'll edit it.
And here, I'm looking at the whole thing.
And if I look down here at content, okay, that's interesting. It looks like it
has -- I didn't know it was going to do this, and I haven't looked at it since
I did it. It broke it out into a whole bunch of linked files. I thought it
was just going to maintain a single folder reference, but it actually broke it
out into a whole bunch of files. Wow, I need to look into that, because it's
really interesting that it did that.
I didn't have to add all of those.
>>:
I just added a reference to the folder.
[indiscernible].
>> Jeremy Foster: I don't think it will, which is the problem. I was hoping
that it would pick that up. Hm, curious. Anyway, so I can reload that
project, close it, yes. And so you can see that the test project has a
reference to the real project. The robe why we're working in this environment
is with the unit tests, oftentimes you just create some assembly with a
reference to your unit testing framework, and then you use that assembly to hit
your project.
But in this case, we have to be a Windows 8 app in order to access like the Win
RT name spaces and stuff. So we create ourselves a real Win RT -- win 8 app,
and then we create that reference to a real project, and then we can access the
stuff in that real project and we can run our tests.
Now, this testing suite is actually using mocha and chai. Those are two
different test frameworks for JavaScript that happen to be really good ones.
I'm really pleased with them. They're really simple test frameworks.
And if you look in tests, I just have one test in here that's doing almost
nothing. But it will show you basically how you describe these. You'll get a
much more robust example if you hope Hilo JS, but I've just got one of them
where I describe a test. Before the test, I said X equal to one or do
whatever. And then I have a test and it's structured when something or other,
this should happen. It should happen that true equals true. In this case,
it's always true.
So then you can run this test, and it's got its own UI. Mocha gives it kind of
UI. It runs in Windows 8 and it runs all these Java tests. So that's pretty
13
slick.
Maybe we should go
test, in my case.
with one unit test
that before. True
ahead and run that. Runs all those tests. Run that one
I feel pretty ashamed having this Code Show app out there
it's Rudd clus. Anyway, N doesn't work. Thought I'd run
is no longer true. It is a bad day.
I don't know what's wrong there. Anyway, doesn't matter. Look at Hilo JS, you
want to see how that works. Let's look a little bit at the overall structure
of Code Show, and this won't be much. Eight a startup project. This won't be
much, but the way I wanted this to work is I wanted to be aible to add demos
very easily. So I have a folder called demos. And inside of demos is just a
whole bunch of folders. One per demo.
And for each of those folders so, for instance, for
maps. I'll expand that and each one is essentially
JavaScript file. The HTML file, I have these lines
yeah, lines six through nine are the meta tags that
bit about this demo. So I say who the author is, I
give it a description.
the -- let's use the Bing
an HTML, CSS and a
six through nine or -tell the system a little
give it some keywords and I
Now, when the app first run, the default JS file is the one that does all of
the kind of startup stuff. It's the one that has the events to describe the
activated and suspended events, things like that. And in here, I call a -when the app is activated, I call this load demos async. I can F-12 into load
demos async and see what that does. And load demos async iterates this folder,
iterates the project folder, and it looks in the demos folder and it looks at
each of them.
And for each of them, it looks for the meta tags and builds this information
and it basically builds up a file. And then I'm also storing some stuff in
Windows Azure mobile services. I'm not finished with this piece of it yet, but
for each of those demos, I want a person to be able to say this demo sucked,
one star. Or this demo rocked, five stars.
Of course, I don't want to just store that in their app because I want them to
be able to see the reviews from all the other people that reviewed it. So I'm
going to be storing that up in Windows Azure mobile services, kind of already
am, and so this is going to be kind of a melding of two pieces of information.
All the stuff that you get local and then all of the stuff that it pulls out of
14
Windows Azure mobile services. And it builds up a collection of all the demos
and does that once at the beginning of the app.
And the important thing here is that the load demos async returns a promise.
So for all you C-Sharp heads, you use the async pattern, which is really,
really elegant. JavaScript's equivalent is the promise pattern. It's pretty
school. I would say it's maybe not quite as terse as the async pattern, but
it's pretty dang nice. It's pretty dang nice. You return a promise and that's
essentially a task. So you know how your tasks are generic? You have a task
of string. So you get a task back, but you get to look at its string. Or we
get a promise, and that promise contains a function that has a payload, has a
payload that is the value that you wanted it to return, okay?
So this load demo is async. I give it that convention. I use the async
keyword at the end to just kind of follow that convention so that somebody
knows this is not going to return to you a value. It's going to return to you
a promise. So it comes back with a promise, and now if you look back at where
I was, where this got called on line 28, on line 28, I set an app level
variable, the demos list. I set that equal to -- sorry, I'm on the wrong line.
The demo's loaded. I set that equal to the result of that asynchronous event.
So this returns a promise. That gets stored here, and now anywhere else in my
app, I can ask that question or have the demos been loaded.
So now I know that nothing else will try to happen until that has happened.
will wait for the demos to be loaded before it, for instance, allows you to
navigate to one or something like that, okay?
It
So it's just kind of an interesting pattern, the async pattern, the way things
are loaded. You do need to wait for it. Of course, it takes milliseconds for
those demos to load, but you definitely don't want to try to do something
before that's actually happened.
So everything in this demos folder is loaded up, including the Bing maps folder
and it's looked at the meta information for Bing maps. It's looked here for
get ready for easy and powerful maps and apps. So let's go look here, and Bing
maps is right here. Get ready for easy and powerful maps and apps. It takes
this from the page title inside the HTML and takes this from that meta tag and
sets it up navigable and everything.
15
So I can click on Bing maps and start to show you the first demo in Code Show.
So on some of my later demos, I've put more meta -- more information in here,
kind of explanatory information. Here's how the demo works. Here's what you
need. Here's your different options and stuff. And I've kind of followed this
slider pattern where I've got multiple things happening and they kind of get
more advanced as you slide to the right.
So for the Bing maps, the goal with Code Show demos is for each one to be
something super simple and super low scope. So that you can just go yep,
that's what I'm interested in. I'll go look at the code and figure out how
that works.
You know how the MSDN samples are pretty robust, and they all have like nine
scenarios, and it takes a little bit of time to reverse engineer the scenarios
and exactly what it's going to do for you and how they implemented that. So I
wanted these to be complementary to that, and so these are very, very low
scope, very simple demos.
So the first one's just showing a basic map, and you can see that the map
works, and if that's all you want to do is start there and include a map, then
that's the one that you should start with. But if you want to be able to move
around on an app, like if you want to be able to go to Seattle or go to Kauai,
then you can use that second one. And then if you want to get into adding some
push pins, you can use this one. .
.
And then if you want to add a custom push pin somewhere, then smed of just
adding a generic push pin, you can add a custom one like this, and now you can
use any HTML markup that you want as a push pin. So that opens up a lot of
possibilities.
Now, since this app is -- you've got the source -- you've got all the source
code, but I also want somebody to very easily, like, say on their Win RT
device, to go to the store, download Code Show, and browse some of these demos
and see how things work.
So I added see the code at the top. So at the top here, I have see the code.
And then once I go to the code, I can switch back to the demo. So this is just
a little toggle nav. When I get to the code, it looks in that folder
dynamically and says what code files, and I tell it what code files does it
have. And then it uses the Alex whatever his name is, that syntax highlighter
16
that you may have seen if you try to use it for blog posts or something, to
highlight the syntax in your code. It's a real popular one. Anyway, I use
that to pretty print this, essentially.
And the only down side to that is that it's not -- you can't select anything,
and that's a big bummer. Number of people have commented in the reviews, you
can't select and highlight and copy stuff out of here. So big bummer. But
anyway, it shows you all of the HTML, all of the CSS, which in this case is
hardly any, and then all of the JavaScript for that app, for that demo.
>>:
A quick idea, couldn't you add an app bar there to say copy code?
>> Jeremy Foster: Actually, I could, and it would copy that entire code file.
That would be better than nothing. But I found a JavaScript library that I
want to plug in that would allow you to just go copy whatever you want in
there. That would be better.
Okay. So you can look at the JavaScript that it takes to do the basic map.
All you have to do is a new up of maps.map, tell it what div you're going to be
dropping it in, and in that case your map options are simply your credentials
and your width and height.
So that's the Bing maps. So now, this is where you can feel free to jump in
and say we want to see that one. I'll be glad to show it to you. But in the
absence of suggestions, I'll just kind of pick some of these. The canvas ball
is a super simple implementation of canvas animation in HTML and JavaScript.
So just have a ball bouncing around on the screen, and you can see that this
one's obviously going to be mostly JavaScript, and you can see how to do that
very simple. It's basically a really light game look there. We've got draw
and step, draw and step, draw and step, draw and step, and that's essentially a
game written in JavaScript.
Of course, they start to get fancier as you add this and add that, but that's
the very basics of a JavaScript game. I got together with the guys that do
reactive extensions and asked them if I could plug in some of their demos into
Code Show, and they said of course. And so I've got a number that begin with
RX. One of them here is RX auto complete. So all of the ones that begin with
RX use reactive extensions. Who here has used that, reactive extensions? One?
Who here is even aware of reactive extensions?
Just a couple.
Interesting.
17
Wow. Reactive extensions is beautiful. There's a whole dot-net implementation
of it and a whole JavaScript implementation of it, and it is slick.
How to describe it in one sentence? I always struggle with this. The guys
that wrote it do much better. But it essentially is an event aggregator. It's
the ability to capture a stream of events and respond it to intelligently as a
stream. Manipulate the stream, filter the stream, merge the stream with
another stream.
So if you are running into a situation where you're capturing events en masse
and it might happen more than you think, imagine like mouse move, mouse move is
something that's going to fire very, very many times. And instead of
responding to that event and asking yourself all kinds of questions in that
event and having all kinds of switching logic, well, okay, the mouse just
moved, but if his button was down and do that, and if his button was up, then
do this.
If you're running into that type of scenario, then look into RXJS or RX.net,
because it might cure a headache, okay? So we're using -- we're consuming
streams for all of these RX examples, and this one I am actually looking on
Wikipedia for results and so this is an excellent way to query for -- to do
auto complete in any sort of an input box. So that's a really good one.
I have RX Canvas Paint. RX Canvas Paint is tracking events like when the mouse
or finger touch. And as they're dragged, and it's rendering canvas artifacts
every time the mouse moves by one pixel, okay? So that's a good way to do
something like ta.
Also on a related note, the drag and drop is RX for dragging something around
on the screen. There are higher level ways to do that, but that's okay.
There's a crop tool that allows you to crop a picture, and there's this funny
time flies that follows your finger with a string of text. So, like, welcome
to 1990 JavaScript.
So those are some RX examples that I have. Has
to see? Okay. Let's look at a sliding div. I
and I want to bring it on. There it is. Super
Windows add SDK. This one will show you how to
project.
anybody seen any that they want
had a div from off the screen
simple. Let's look at the
bring an add control into your
18
So if you see the code on this, you can see the way that we do controls in
JavaScript. You know, in C-Sharp and XAML how to do it. In JavaScript, here's
how to do it. You have a normal div tag, but you give it these two attributes.
You really only need the one in some cases. But there are two attributes.
Control and options.
The control is the full name space and control type of the control that you
want to turn this div into. And then options is an adjacent string that you
want to pass into that control as options. As, like, attributes. And then the
framework, the Win JS framework is responsible for looking at your whole app
when your app first runs and saying find all of the data win controls and turn
those into controls.
So it's going to go through and say, okay, here's the element. They wanted me
to turn that into an add control so the add SDK is responsible for crunching
that and turning it into an add control. Okay? So that's how we do controls.
This is just a super simple one that brings in an add, and I like to sit here
and just refresh this over and over, and I highly suggest that you guys do that
too.
>>:
Maybe we should copy/paste that code in all of our map IDs.
>> Jeremy Foster: Yeah, same credentials and everything. Here's a decent one
that I just added for the latest video series that we did on MVA. This is the
WAMs push notifications. So if you're interested in doing push notifications
and you don't want to write your own service, then you can use WAMs for this.
It's really easy to sign up, to create an app, a mobile app in WAMs.
And for employees, you can do the whole thing for free anyway.
So you go into WAMs and you create yourself a mobile app, and I already had one
for Code Show. But to write this, I basically just went in and said I want to
enable push notifications. I created a table, and I just set it up so that
it's really simple. Really simple push.
And in just a second, I'm going to see a toast pop up on the screen. What's
actually happened in that time between when I pushed push and when that came
down is I wrote a record into WAMs, into a table, and the script in WAMs said
hey, a record was added in this table, and it's configured. I wrote the script
to pick up that record and call the push API and push that to the person that
19
is using this app and this device specifically, okay?
So I've given it what's called a channel URI so that it knows me and this
device uniquely, and so it knows exactly where to deliver that notification,
okay? So it's possible from your app to just do a toast notification, but I
didn't cheat and do it that way. It actually is going to WAMs and coming back
and doing that push, okay?
So if you want to see the code for that, the HTML is obviously very simple.
It's just an input and a button. That's it. The CSS is nonexistent and the
JavaScript looks like this. I put my WAMs context or client, this is kind of
the root of the SDK. I put it in my app variable once again so that you can
glance at it there and see -- or not so that you can glance at it. So that you
can use it from anywhere in your app. You can always do app.client and you're
referring to that WAMs instance.
So I get the WAMs push notifications table which I created in WAMs. And then I
do an insert and I'm inserting the channel URI, the message that the user typed
in and whether or not that message has been sent. And the way I actually
structured this is every time you write into it, it enumerates the whole table
and picks up any that haven't been sent yet and sends them. So if there happen
to be more, it would send them as well. Yeah?
>>: So I [indiscernible] WAMs push notification. It seems like you can only
send push informations to yourself. Am I not understanding something.
>>: Yeah, I think the comments are something happens and you want to send a
push notification to users of your app that are related to [indiscernible] say
you have chat or you're playing a game. Yeah, so is that something that's
supported?
>> Jeremy Foster: So the question is can the notifications only be sent
yourself, or can they be sent to the right person? The answer is they can be
sent to the right person. It depends on the channel URI. That might be where
you're getting hung up. The channel, as soon as -- I've got a post online that
show make this clear. It's called anatomy of a push. So if you go to
codefoster.com/anatomyofpush, it will take you to this blog post, and what's
happening is the green is you. You wrote an app on Windows 8 and you wrote a
web service. If you're using WAMs, this is easier. You didn't have to worry
about this.
20
But your app, when you start up your app, you do a call to window and you say
give me a channel. And it says, okay, I'm a device and I'm a year. I know
this, and it goes to WNS and it gets a channel and gives you back that channel.
Now, you're responsible for storing that channel. So in the WAMs scenario,
that's why you saw, when I created a record in the table, I stored the channel
URL as well, and if you need to, you can store that channel URL. It doesn't
expire for 30 days. You can store that channel URL with user information. So
as soon as the user launches the app, now you know what the channel is for that
user. You've got it stored.
So, for instance, you could store it in a user's table. Here's their channel.
And every time they open the app, you could refresh it just to make sure that
you don't expire within po /#30* days, you know, outside of 30 days. And then
when something happens, like another table gets written to that this person has
a message waiting for them, you can go to the user's table, find their channel
URL and send a push notification to that channel URL.
>>: I think the key there is that the push app [indiscernible]. So within
WAMs, you determine that this other thing happened that you need to send the
push, so yeah, one user can't send a push to another user. The WAM app does
that for you. Maybe that's where the confusion comes in.
>>:
So you write the script on the WAMs side?
>>:
Yeah.
>>: So if I have, like, say a different database that I keep track of my
logic, can I get off to that database and figure out which users to send the
information to?
>> Jeremy Foster: If your database is completely external system, then you're
going to have to have -- like WAMs is going able to to do raw requests. It's
basically written on node, and you can pull in requires to the WAM scripts.
And if you have a way of communicating with your database that way, then yes,
you can do that. Otherwise, you can communicate with raw SQL calls to the
database that you've got sitting underneath WAMs, and then what were you going
to add?
>>:
I was going to say [indiscernible] server gets the push, [indiscernible].
21
So you can build [indiscernible] when something happens, you can call your
[indiscernible] and say I want to do this action [indiscernible].
>> Jeremy Foster: Right now, the first iteration of WAMs was able to do a push
only triggered off of a cred operation on the database. Then they put in
another iteration of WAMs where you can have scheduled operations, and if you
have a free tier mobile services, you only get one operation that you can
write. But if you go up to share, then you can write more. And these
operations, you can schedule them to run every 15 minutes or every 24 hours or
something, or you can make it so you manually trigger that operation.
So now you can trigger an operation for some other reason. So if you wanted
to, you could have a database of users with their channels that are getting
updated every time they use their app, and then every 24 hours, you could look
through that table and say, is this user expecting to see something or
expecting something to happen? Then go ahead and using the channel URI stored
in the user's table go ahead and do a push to them. Now you've got it
happening on a schedule.
>>: So another thing, [indiscernible] even though WAM supports only
[indiscernible] operations, you need to [indiscernible] you can just say
[indiscernible].
>> Jeremy Foster: In other words, you can trigger a WAMs operation by writing
into a table, but then not even actually completing the write. Because once
you override that script, the insert method, you see inside the method the
actual execution of the insertion of the record and you can just kill it.
>>: It's not even killing it.
[indiscernible].
It's just like say sort of writing
>> Jeremy Foster: It feels like a [indiscernible]. At the end of the day, it
works. It's not a hack, right? The push notification, the communication
system in this anatomy of a /PURBGS I talk about what the messages actually
look like, the HTTP messages going back and forth. But then WAMs make it so
you don't even have to deal with that. So it's pretty nice in that case.
Would it be helpful to see -- would anybody else like to see like my mobile
service online? Okay. Let's go ahead and look at that. Azure is one of those
things I'm incredibly excited about. I love going to my dashboard in Azure and
22
seeing all of the -- you'll see all the stuff I've got going on. I mean, media
services and mobile services and websites. I recently moved my whole blog over
to an Azure website and I've been really thrilled with it.
Okay. So this shows you everything. It's not a helpful view, in my opinion,
but I'll go into mobile services. You can see I've got a few. One of them is
called Code Show. It's obviously the one sitting behind Code Show. And when I
go to the dashboard for it, it shows me, you know, here's how this is being
used as Code Show is operating, it's communicating with this. Actually,
probably as I show this, we're going to see a few of these hits for the push
notifications.
If I go into data, I'll see this WAMs push notifications table. And if I go
into that table specifically, I can see the script for that table, and this is
where that one is being done. Actually, I should have stayed on browse long
enough for you to see the structure of that table. This use es -- I love the
way they did this. So it's sitting on top of SQL server or Azure SQL
databases, and so you have a full SQL database. But it's wrapped in kind of a
nice modern UI. Not just the UI here, but it's wrapped in a no SQL
implementation. So it's really easy to read, write and everything.
It feels like no SQL in that you can shove whatever you want into it, but it's
actually dynamically creating those columns for you. We call it dynamic scheme
tiesation. If I were to send it an object, remember I was sending it an object
that had channel message and sent, the ID is always just done for you. If I
were to now send in an object that had one more column, it would actually go
alter my table in my SQL Azure instance. Alter my table and add a column to
that table. And I'd have a number of records that didn't have a value, because
I made them beforehand, and then I'd have a column that had values in it all of
a sudden.
So here's my channel URI. Some of these might be expired. Maybe I did them
more than 30 days ago. So some of those might be expired. And then here's the
message that these wrote, and these are true, but all I do to trigger a push is
insert into this table with this as false, and then how does that trigger
happen that's in the script.
In the script for this specific table, I have an insert trigger. And this
is -- I forgot your name. Sanjif was talking about this.
Dot -- request dot respond, but here's the request.execute. When you first get
23
here, this is all done and it looks like a request.execute.
insert statement.
That's the actual
Before that, what I'm doing is I'm saying go ahead and do the insert and then
when you succeed at the insert, do this. So I go get that table. I loop the
whole table and find all of the ones where sent is false, and I do this to
them. And this is doing the actual push.
So here's the actual push. Push.WNS, send toast text. By the way, if you're
wanting to talk to an iPhone, it's just push dot -- is it ANS or AWS or
something like that? There's another object there for communicating with apple
push notification server. And same with any other push notification servers
that we support.
Hope that's helpful. In XAML, you know what grids are, right? You've been
using them forever. Just the grid. Not a grid view, the Windows 8 list of
items, but a grid. Well, we got grid in HTML now. So we can kind of play on
the same turf here. The grid is just like the grid in XAML, the grid allows
you to define rows and columns and allows you to place the elements in there
including row spans if you want. You can use it to create fancy layouts and
stuff in HTML and JavaScript and here's a fancy one that's like a huge grid
that I obviously generate automatically in a nested loop.
But we've got grids in HTML and that's significant. We've also got a thing
called a flex box, and I think this is roughly equivalent to your stack panel,
except that it also can wrap. I don't know if a stack panel can wrap. It
handles its own -- I think in XAML, in Windows 8, don't you have to put things
in a scroll viewer if you want them to run off the screen and scroll? The flex
box handles that automatically in JavaScript. So that's pretty nice.
You just, you don't even specify anything as far as width. If your items push
it to 5,000 pixels wide, it will just -- in other words, it will work naturally
with touch. So there's a quick flex box. There's one where I've told the
children to distribute themselves. One where I've told the children to stretch
a little bit, you know, like allow them to flex. And here's a wrapping one and
a vertical one. And then here's -- this is kind of like an implementation of
flip view, but this is just a simple flex box.
And actually, this is the same type of technology that I'm using to do this
swiping. It's really simple. I basically -- notice that I have this one
24
peeking on told screen. I did that by saying I have a flex box. And if this
has the class of swiper, then I have some CSS that applies to it. And one of
those is that every panel should be 80 percent the width of the screen. That
means the last 20 percent is going to allow the next panel to peek on to the
screen.
So now I can just do this. Well, if this was a touch projector screen,
wouldn't that be great? And I love the way it handles touch in here. Notice,
when I touch inside -- I need to turn on my touch point. Does everybody know
how to do that? If you go to settings and type tough, there's this change
multi-touch gesture settings, and it allows you to optimize visual feedback for
projection to an external monitor. That's pretty slick.
Now when you want to show off how something works, you get a little touch point
there. How many people knew that? I love bringing new things. That's
excellent.
Okay. So when I touch insight here, first of all, watch this. It knows that I
can go vertical in that. By the way, that's not good UI. Not good UI. Listen
to whey you say, not what I do. If I swipe to the left, it knows that I'm
inside that control so it swipes to the left. But if I grab it and it doesn't
have anywhere to go, then it passes that gesture up one and now it's swiping
the control above it.
>>: How does that work? Like really, I have had issue if you have
[indiscernible] vertically, right. Then what [indiscernible] like how does the
control [indiscernible]. You do it this way, like either [indiscernible].
>> Jeremy Foster: I don't have any logic in my code whatsoever. It actually
reads your mind and there's a different signature for I'm about to scroll up
and down, and it reads that brain pattern and that's how it sets it.
No, it actually, exactly like you said, it looks at the delta, like the first
movement that you make, and now you're locked in rail. So notice I'm going
side to side, and it's not scrolling side to side at all.
>>: Like if you have a list view, same thing, like it will scroll -- you put a
list view [indiscernible].
>> Jeremy Foster:
If you hit list view and the very first thing you do is
25
scroll directly horizontal, it will work.
>>:
It should work.
It's almost impossible [indiscernible].
>> Jeremy Foster: I don't have too much trouble with it here, like
going vertical and there I'm going horizontal, and I get that right
time. I mean, I still goof it up sometimes. I want to go vertical
sideways a little bit, and then I'm like oh, it won't go vertical.
let go and grab it again. I feel like it does a pretty good job of
>>:
there I'm
most of the
and I go
I've got to
discerning.
[indiscernible].
>> Jeremy Foster: It's interesting, the way the -- if you go to Internet
Explorer and you look at any page that pans. So I'll go to something like
MSDN, because it's usually got lots of data on it. So it's got some -- well,
this doesn't have any horizontal, though. So the way that Internet Explorer
works is it looks at your very first movement and if your very first movement
is in the up and down direction, then it puts you on rails. In other words,
it's only going to scroll up and down.
If your first movement is diagonal -- can anybody think of a web page that has
horizontal, like, wider than one screen and taller?
>>:
MSN.
>> Jeremy Foster:
>>:
MSN?
No, same thing.
[indiscernible].
>> Jeremy Foster: What? Click on the headline? Oh, no what I mean is that
the web page itself is wider than my screen and taller than my screen.
>>:
Can you zoom and make it --
>> Jeremy Foster: Oh, that's a good idea. I can zoom. Brilliant. Give the
man a star. So now I might want to go side to side, and I might want to go up
and down, and what it does is when I first start going up and down, if it was
straight up that I went, now I'm on rails. I can't go side to side at all.
And I like this because let's say I'm reading an article and I've kind of got
it lined up on the left. Now I just want to read the article. I just want to
26
go up and down. I don't want to accidentally get this side to side.
want that much freedom.
I don't
But if my first gesture is diagonal, now it's wide open. From the rest of that
touch point is wide open, okay? If my first gesture is horizontal, I'm on
rails. I can't even go up and down. But if my first gesture is diagonal, I'm
wide open.
So I got into the habit of starting a gesture diagonally if I want to look
around a little bit. So you might want to get into that habit.
So I didn't have to do anything special to make this work. I basically just
have that same swiper control. It's not even a control. It's just a class
with some CSS. I have it on the inside and the outside, and there's actually a
CSS property. I think it's an MS pre-fixed property to override this control
so that it doesn't pass that touch up to the parent.
>>:
Is that CSS?
>> Jeremy Foster: It's in CSS, yeah. It does seem strange. So here I'm able
to swipe this to the left. But once I got all the way to the left, now a swipe
still inside of there scrolls the whole thing. Same thing is visible if you go
look at the list view demo. List views.
So these are list views, right? And they have stuff inside of them, and I can
swipe on the inside. Even in the same gesture, watch this. I'm swiping, I'm
swiping, I'm swiping. I get to the end and the whole thing starts panning.
That's pretty click. I think te did an excellent job with that.
So in XAML, you have a grid view and a list view. Right? A grid view looks
like this, and a list view looks like this. In HTML JavaScript, we don't have
both. All we have is a list view and we tell the list view to be a grid layout
or a list layout. So we just have one control.
Same concept that we have the one control. So this is a list view in grid
layout. It's the equivalent of the XAML's grid view, okay? This is just a
simple one so it's just bringing in some data. Here's bringing in some data
that's grouped, and so the code behind this is really super, super simple so
that you can see exactly how to bring in grouped data.
27
And then here's how to do an asymmetrical grid. Has anybody done this, even in
XAML, done an asymmetrical grid? You've done that? They're really not that
difficult. What you want to do is figure out what your atomic size, item size
is. In this case, it's this one. I don't remember what the size of this is.
This one is four of these. This one is two tall, and this one is two wide,
right? So when I bring this data in, I can conditionally say I want this one
to be a class, a CSS class that indicates that it's going to take up four
spaces, two spaces, two spaces. But they're still brought in in order. So the
order of these is like one, two, three, four, five, six, seven, eight, nine,
ten. Can everybody see that? It's like this one goes here, here, here, and
then here. It happens to take up two vertical, and then it moves to this one.
No, I'm sorry, then it moves to this one. And then here, here, here, which
takes up two spaces. So then here, here. Now, I would really run into trouble
if I was expecting to be able to put something here.
In fact, if I -- sometimes you have to add
you don't end one gaps. So in other words
this one, then it wouldn't be able to land
it so it would jump up here and I would be
some logic to here to make sure that
if my third item was too tall, like
here. There's not enough room for
left with the hole here.
So if you want to do an asynchronous grid, you may have to do a little bit of
logic to make sure that it fits together like a puzzle and you don't end one
any gaps.
I imagine somebody's maybe written some logic and wrapped it in a control or
something by now. But maybe not.
And then again, I don't know if you guys have done this in C-Sharp, but I
figured out how in JavaScript to capture -- not that I figured out like it was
rocket science. It wasn't all that difficult. But to capture the loading
event or the loading state changed event and figure out when the loading state
of this guy changes. And each time it does, I can ask it what's the current
loading state so I can figure out that the view port has been loaded.
So the basics have been set up. The items have been loaded so all of those
items are done and now the whole thing is complete. This was really important
for me, because there were some things that, like anytime I wanted to go kind
of dynamically inject thing into the items or ask -- go query the items, I
wanted to not do that until the list view had been completed. And if I tried
28
to do it beforehand, this weren't any items.
this was really important.
They hadn't been built yet.
So
Also, if you go back in Code Show, it takes you to the scroll position that you
had. At first it didn't do that. I don't know if it annoyed anybody else, but
it sure annoyed me. I would go into a demo and hit back and I would be all the
way back at the beginning again. It drove me nuts. So I was storing that
scroll position and then I was trying to reintroduce the scroll position, but
it wasn't working.
And it's because the items hadn't been loaded yet so I wait until the list view
is loaded. Actually, I don't wait until it's loaded entirely. I wait until
the view port has been loaded and it turns out that works. And then I add that
scroll position and it takes me to that scroll position. And it's seamless.
Like when I did it and I waited for it to load, I would go to one and I would
go back and it would be like go to the beginning and then flash to the end.
That wasn't acceptable.
So now I've got it so it's seamless.
So that was nice.
>>: Wasn't that way too hard? I mean, I had the same problem with my app and
I spent three days trying to figure it out.
>> Jeremy Foster: Yeah, that was maybe too hard. Yeah. Anybody use player
framework? This was really easy to add in. It's just basically an example
from where I got player framework. I believe it's on codeplex. It's a
codeplex project, but it's a wrapper for media that makes it so that it's got
really good fail case scenarios, where if they have this, they use it. If not,
then use this. If not, then use this. So kind of wraps your media and makes
it nice and safe so that you're guaranteed that your media is always going to
play. You're never going to be left in front of a crowd with a black screen.
That's what it's there for.
Template items is kind of a fun one. Template items, let me open that again.
Actually, I've just got to click here to reload at the top. When I reload
this, you can see that everything kind of comes in on an animation, and we get
these animations for free so we kind of take them for granted sometimes. But
it's really cool that we've got a whole animation library in both XAML and in
HTML that we can capture.
29
And on this one, I can click on any of these and they disappear and it uses
the -- that's not good. It uses the remove from list animation, pulls that
item out of the list and you see the rest of the stuff collapse.
Those animations end up being super, super helpful. If something just
disappeared and everything else took its right place instantly, you really
wouldn't notice what happened. But when you touch something and it removes it
and everything else repositions, it looks more like reality. That's really
helpful. We always say make sure that your animations have a purpose. You're
not just using them superfluously to add some movement. You want make sure
that there's a reason for it. A page turn can of kind of shows moving on,
moving on, moving on. Remove from list shows I took it out, else slid into its
place.
So snap points. Snap point make sure that as you scroll, you land not in
between two items, but you always land at a snap point. It will take you there
if there isn't one. I don't know what the equivalent to XAML is. Does
anybody?
>>:
I think there's something called snap point.
>> Jeremy Foster:
done in CSS.
>>:
It might be a property.
Might be a property.
This one's
I think it's a property of [indiscernible].
>> Jeremy Foster: Yeah, okay. Let's actually look at the CSS for that one,
because I'm forgetting what it was. So here's the CSS. Snap points, it's an
MS prefixed. I like the way MS has implemented all of their CSS. It's all -actually, their JavaScript in hidden Markov model HTML as well. It's based on
the standards, but it's something Microsoft proprietary anyway, like snap
points in apps. Then we use the vendor prefix. But if this concept ever gets
successfully through the W3C process and becomes an RC, then the prefix would
fall off. And that's a good deal.
So we're saying these are mandatory, meaning it has to land on a snap, make
sure it gets to one even if it's close enough. It's either mandatory or
proximity. You have to give it the interval. I kind of wish I was able to put
the snap points declaratively in my HTML or inject them logically with my
JavaScript and say there's a snap point and there's one. I can't. They have
30
to be at intervals. They can be at percentage intervals or at absolute
intervals, but you have to set them at intervals.
Okay.
>>:
Somebody else pick one.
CSS animation.
>> Jeremy Foster: CSS animation. Colleague of might be made that one, so I
might not know everything about it. Where's it at? Animation. Okay so don't
click me makes me angry. Just makes me want to click it. So you touch it and
it runs through some animations. Just the changing of properties on that guy
and it resets.
So if you see the code on that, you're going to see in the CSS where all the
magic happens, here's an actual animation with key frames. It's the equivalent
of a story board and I believe it's the equivalent of story board in XAML where
you get to say at these points, these are the property sets that should apply.
And then obviously, it's going to run through that. So this set of key frames
is defined as Get Angry.
And then this property or whatever the element is has this class and we're
applying the Get Angry animation for five seconds. And so that's the way we do
it in CSS.
>>:
Simpler than story board.
>> Jeremy Foster:
angle brackets.
>>:
Yeah, story boards end up with a lot of UI, right, a lot of
[indiscernible].
>> Jeremy Foster: Yeah, right. Luckily, we've got blend, huh? The NetFlix
examples show there's three NetFlix examples. If you do just the NetFlix data,
it the most basic and I believe it waits until all of the data has been loaded,
and then bam, you see it all loaded once and there's something goofy with that.
>>:
[indiscernible].
>> Jeremy Foster: With the display. It's overlapped. See there, it's right.
I don't know why it didn't work the first time it loaded. I haven't seen that
31
before. So this one is making sure that everything is loaded and then, bam,
it's showing you all the data.
And the NetFlix by ten. So actually, the NetFlix data was bringing in a
random -- I think it's like a thousand different movies or something, and so
the letters, like I and K, there's not even a J in there. They only had one
movie, and there were no Js. So the NetFlix by ten goes through the letters of
the alphabet and says for each letter of the alphabet, do a different call.
And get ten movies that begin with that letter.
So it's just kind of a different way to call it. So NetFlix by ten will end up
with a bunch of NetFlix movies coming down from the API, but there's always ten
per movie, okay? And then the NetFlix trickle is the way to use promises
intelligently to do the call but bring them in and show them, even before, like
if I can beat it in speed, see, so some of them have come in and some of them
haven't yet.
It actually shows them as soon as the request comes back. So essentially, it's
a list view that's based on a set of data that's empty at first and then I do
26 different calls, right? 26 different letters of the alphabet. So I do 26
different calls and if J comes back first, put the J letters in there, and
they'll show up. And then A comes back next. So put the A movies in there and
they'll show up. And that's the way to bring them in on a parallel format.
>>:
[indiscernible].
>> Jeremy Foster: I think they will not go out in more than eight at a time.
The HTTP stack on your computer, there's going to be limitations. If you try
to send out 26, it's not like you get all that much advantage anyway, and so I
think that it's eight currently in IE, and I think it would use that same
number for JavaScript apps in Windows 8. But I can't be sure of that. Now
that you bring it up, makes me really want to go look that up. Remember, it
used to be two. Did anybody run into that? In IE, like six or five or
something? So you'd go into the registry and turn it up to four or eight and
then you could download more things at once? Those were the days.
>>:
[indiscernible].
>> Jeremy Foster: All right, any more that we want to see? And we'll end here
in five minute or so. Oh, you know, right promises one I think is really
32
helpful. The promises one I tried to start by showing you the concept of what
a promise is, and then by showing you four different ways to do promises and
then showing you some good syntax for chaining promises. So if you look at the
concept, so watch this. When I hit start, it will freeze my UI. Every one of
these tasks takes three seconds, by the way.
It will freeze my UI for three seconds, which is not a good experience. So
bam, my start button is even frozen. I wouldn't be able to hit back. I
wouldn't be able to do anything, and then it finally completes. So that's not
a good experience because I'm freezing my UI.
The next one is kicking off a three-second task asynchronously. As soon as
it's done kicking off that task, it's completing that progress bar. So that
one's not a good experience because it's a lie. It's telling you I just
finished. It didn't actually finish. It just kicked it off, right? It just
kicked off an asynchronous task but didn't wait until the end.
So we want to kick off async, but then we want to wait until it's done and then
do something else so that's why we use a promise. Now we can not only say when
we get done, but we can get the event that fires whenever progress occurs so
now we can show intermediary stage and now we're giving the best experience to
the user, okay?
So that's the reason for promises. That's the reason for async and. In
JavaScript, if you're just calling an async function in the Win RT library,
like if you're calling show async on the message dialogue or something, you do
a wait, right? That's kind of the consumption of an asynchronous method. And
that's what a consuming a promise is. You're calling an asynchronous method,
consuming it and you do a dot then.
So the code behind this one, all of these just work the same, but the code
behind that first one just does a dot then to not complete that progress bar
until the three seconds is up. Now, this one is passing on a promise. This is
the equivalent of writing your own async function, which calls an async
function and then returns whenever that one is done.
So you're awaiting something and then somebody's awaiting you, right?
Equivalent. Creating a promise is the equivalent of creating your own async
function. Doing whatever you want in it and only returning a certain time.
And then storing a promise is the equivalent of saving a task of type whatever
33
and then referring to that task later on in your app.
I found a number of cases where I want to do this like I showed in Code Show.
Go do something and store the promise that comes back immediately right here,
and then at various places in the app, I'm going to go ask that promise, are
you done? Did you finish?
And if it finished a long time ago, it will just happen right away. So that's
great. I'll just go if that is done, if that promise has been fulfilled, then
go ahead and do this. How do you do that in C-Sharp? Do you task like is
complete? Or await task? You still just await the?
>>:
You take the variable and you do whatever when you finally want --
>> Jeremy Foster:
>>:
Awesome.
[indiscernible].
>> Jeremy Foster: So no, there's not necessarily something like the TPL. We
do have parallelism, but you have to spin-off different web workers, they're
called. It's a web standard. And you can use these web workers, but it's not
integrated with the promise pattern, necessarily. So I'm sure there's a good
pattern to utilize it well, where you can, inside of your promises, you can
launch different web worker, and then you're kind of doing roughly the same
thing.
But I've used the TPL a lot, and it kind of merges the two concepts and makes
it nice and easy for you. It's not quite that nice in my experience, unless
there's something that I'm missing. But it's not quite that nice.
You can join a bunch of promises together so I've got 26 different promises out
there, and I can join them, meaning wait until all 26 have completed and then
do something. You can really easily wrap anything you want in a promise so if
you're returning a value and who you're returning it to is expecting a promise,
you can just do winJS.promise.as and then pass your string and it will pass it
as a promise with a string in it.
So there's a number of things to help you with promises. And then the chaining
is just some of these three-second events happening one right after another.
So this one's not so helpful unless you see the code. But it shows you the
34
right way and the wrong way to do your chaining. So in C-Sharp, you kind of
have to do it right. Await this, await this, await this, await this, right?
In JavaScript, we actually have a little function thing so if we look in the
wrong way to do it, in my comment here, you start ending up with the Christmas
tree pattern. If you're nesting inside of your then, you're nesting another
promise and another one, another one, another one, pretty soon you're way deep,
this is the better way to do that.
It's cool the way it
return, even if it's
kind of passed on -tacked on to it, and
works, because inside of a then function, whatever you
not a promise, will get wrapped with a promise, and it's
not passed on, but the next dot then that you have is
so this one's always receiving a promise.
So you could return a string and then in the next then, you could capture that
string as a parameter and return an integer and then capture that integer as a
parameter. And we use the then, then, then pattern. Then, then done. We
always use thens until the last one, and that's one's a done. Because it has a
special way of handling exceptions. It makes sure that you haven't let any
exceptions get swallowed.
I'll bring it back to the main screen and if there's any more that you guys
want to see, let me know. Otherwise, we can just kind of turn social and ->>:
I was just curious about the encryption.
>> Jeremy Foster: So the cryptography in encryption. This one I'm not very
proud of. It basically, it doesn't help you too much unless you go back and
see the code, and I had to show this in a presentation and so I had to have
something in here, but all it really does is run some of the same things that
you see in the sample on MSDN. So I would just go look at the samples on NSDN.
They're a lot better than this one. It will do a couple of simple things, like
you can create a [indiscernible].
>>: [indiscernible] the basics for encoding and decoding. If you are wanting
to save a [indiscernible] and then you can use the [indiscernible] if you want
to save the current state, then you can do that.
>> Jeremy Foster:
Is that the only way to save an image from the canvas?
35
>>:
That's all I know.
>> Jeremy Foster:
>>:
Wow, that's really cool, though.
[indiscernible].
>> Jeremy Foster: So that's the same thing as if I do like two
URL.createobjectURL. To take an image, turn it into a base 64 strain and set
it as the source of an image, right? That's really cool. That one is used in
the media capture demo -- the first one is image, the second one is video and
the third one is audio. And for the image, you capture and it launches the
camera capture UI. So there I am and I touch it, and then I can crop it if I
want and I'll get it rough -- that's a terrible picture. I'll get it roughly
right and then I'll hit okay. I didn't get it roughly right.
But now it has converted that to a blog, to a base 64 string and set that as
the source of this. So I didn't actually save an image on disk and then set it
as the source of the image tag. Instead, I actually created an object URL and
did it that way.
>>:
Just one more thing.
>> Jeremy Foster:
>>:
[indiscernible] took me two months and [indiscernible] to figure it out.
>> Jeremy Foster:
>>:
Do you have a blog post?
Yes.
>> Jeremy Foster:
>>:
Um-hmm.
Will you email it to me?
Sure.
>> Jeremy Foster: Great, excellent, because I have an app that I'd love to use
that in, actually. I forget exactly how I'm doing it.
>>:
When you can save it locally and share it, but that's [indiscernible].
>> Jeremy Foster:
Agreed, agreed.
That's really helpful.
Yes?
36
>>: I just wanted to make the announcement that our AKA.MSmeetmyapps forum is
now live. So go sign up now if you want to present in two weeks from today.
>> Jeremy Foster:
And we'll basically take those first come, first served?
>>: Yeah, it will be first come first served. We might select more than one
if we have a ton of people sign up. But we'll try to keep it at a minimum -at a maximum /PROERBLGS two or three per week.
>> Jeremy Foster:
>>:
Exactly.
I'd say two, so we can spend five to ten minutes on one.
A more exciting platform to talk about your app.
>> Jeremy Foster: Yeah. Anybody know that they're going to go sign up for
one? Can you raise your hand if you're going to sign up and show something?
Awesome. Good. We'll have a few, then. That's good.
Fly-outs are one of those areas that are easier in HTML JavaScript than they
are in XAML. The flyout, you can pass an anchor, and that's where the flyout
appears. And in XAML, you can't easily make a flyout appear in a certain spot.
I guess in the calypso package, there's a fix for that. But it's really easy
for us to hit flyout and say that button is the anchor for my flyout and I want
to show up on the right side of it. So boom. It brings that up.
Anyway, that's it. Let's go ahead and fold, huh? So feel free to stick
around. I'm going to be around for a few minutes. Feel free to help us finish
off those sandwiches or take a couple home. The next meet-up is not entirely
confirmed, but it's two weeks away. So you'll get an invite, hopefully sooner
than you did on this one. I think I just sent out the invite four days ago.
Sorry about that. But the next one is supposed to be on sky drive and live
integration. Question?
>>: Just a reminder, if you guys know anybody, employees, vendors, interns
that would be interested in joining us, go ahead and forward them our meeting
invites and encourage them to sign up for the [indiscernible] alias and Jeremy
includes that in his notes that he sends out each week. I wanted to remind you
guys, help us get the word out. The more people we have coming to these, the
more we can spend on tasty treats and prizes for our [indiscernible] that we
end up doing but I just want to make sure and remind everybody, help us get the
37
word out [indiscernible].
>> Jeremy Foster: Likely going to send a poster soon and ask you if you'll
post in your building on a common billboard or something so we can get the word
out to more people. So cool. Thanks for coming.
Download