Placeholder Image

字幕列表 影片播放

  • WARD BELL: OK, well, I'm going to start.

  • I'm Ward Bell, I'm VP of technology and a founder of

  • IdeaBlade, a company in the Bay Area.

  • And I'm here to talk about Angular and Breeze.

  • Breeze is our product and Angular is a Google product,

  • and they work really well together when you're building

  • CRUD apps, which is Create, Retrieve, Update, Delete,

  • something like that.

  • Anyway, if you business apps are a very

  • typical part of this.

  • I come from the Microsoft arena.

  • We build a lot of business apps there.

  • And so building business apps is kind of what

  • I know a lot about.

  • I don't know how to build games, but I know how to build

  • business apps.

  • And because I don't know how to make games, I can't be

  • Huggy Bear, because I can't do a lot of bling.

  • So I have to do the thing that a lot of business developers

  • get paid for, which is to build business applications.

  • And you can call them Line Of Business applications, that's

  • LOB, and CRUD apps.

  • They kind of go together, because they're all about

  • asking for data and saving data and stuff like that.

  • And the typical category is ERPs, and I wish I could--

  • Enter source, Resource.

  • You know how you know the acronyms, you

  • don't know the words.

  • CRM, Custom Resource Management, asset tracking,

  • call centers.

  • The kinds of apps in which users sit in front of them for

  • long periods of time and they answer questions like, I've

  • got to go find all the orders and I've got to fix them.

  • Or I've got to book a premium three-week vacation or renew

  • rail cars, or something like that.

  • These are the typical tasks that people sit in front of

  • them all day long.

  • And really what the modality is that's pretty common across

  • all of them, is that the user sits there are tries to find a

  • target data set to work on like orders and

  • something like that.

  • And then the application pivots around that data set,

  • looking at it from different angles as they process it.

  • So they're not surfing all over the place.

  • They just find what the customer is interested

  • in and go at it.

  • And so from a computing perspective, it's really a

  • small set of data.

  • But from their perspective, it's not so small, because

  • it's about what fits in their head, fits in

  • their attention span.

  • So they usually just grab onto a chunk of data and then sit

  • with it for a long time.

  • Now because they work all day long doing that kind of thing,

  • the most precious resource is the user.

  • And so the whole idea is to say, let's move all the

  • computing right there.

  • Let's have client side computing,

  • client centered computing.

  • Another term for this might be SPA, Single Page Application.

  • You could think of it as Ajax applications, HTML JavaScript

  • app, whatever you want to call it.

  • We call it SPA a lot where I come from.

  • That's it.

  • And Angular JS ought to be really good at it because of

  • what you just saw.

  • And it turns out it really is.

  • And so what's happening is that a lot of people who are

  • in the Microsoft space are seeing this Angular thing

  • coming, and they're kind of interested in it.

  • And one of the reasons--

  • well, there's a list of reasons about why they are.

  • For one, it's comprehensive.

  • So it does a whole lot of things.

  • You don't have to buy a whole lot, or get a

  • whole lot of libraries.

  • It does screen.

  • You can handle screen management, and dependency

  • injection, and a whole bunch of other things that you can

  • learn about.

  • It's really elegant to work with, which is nice, because

  • there are some other comprehensive ones that just

  • seem like you write, and write, and write, and write,

  • and write, and write, and write, and you can't figure

  • out what their head was about.

  • So it's nice and terse.

  • Some people really like that it isn't sitting there

  • listening for observable, so I don't have to have special

  • purpose objects that raise notification events.

  • And it has a lot of momentum.

  • There's a lot of people working to make Angular better

  • all the time.

  • And it's getting a lot of traction.

  • So lots of reasons.

  • And there are people in the Microsoft space who are very

  • well-known there who are writing about it, like my

  • friend Scott Allen here.

  • So anyway, you start to do it and you're the captain of your

  • Angular luxury cruise liner.

  • And really your job is to make sure everybody has a good

  • time, and you don't end up on the rocks.

  • That's really your only responsibility.

  • Just keep it moving.

  • Keep them happy.

  • And so once you're doing it, you'll see that really if we

  • think about that liner, there's the entertainment

  • section up above, which is where you do the presentation.

  • And that's where Angular is really super strong.

  • And if you're doing the line of business stuff, there's all

  • that data access stuff.

  • And that's where Breeze is going to come in.

  • So you could say we're going to help you build applications

  • from A to B, except that doesn't sound right.

  • Anyway, so remember it's fine to target data set and

  • pivot around it.

  • So it's a lot about data.

  • And what do I mean by pivoting around it?

  • Suppose I had an application that was for scheduling a code

  • camp and there were sessions.

  • Chances are you're going to have to pick your session or

  • edit a session or do something like that.

  • Well, the session keeps occurring from screen to

  • screen to screen to screen.

  • And you're really talking about the same session as you

  • look at it from different angles and

  • make different changes.

  • So here we have this class by [? Scott Gould ?]

  • appearing in four different screens.

  • And when you finally look at one of the items that's in it,

  • you'll find that the data that are behind it, it's not just

  • one object.

  • It's usually backed by a SQL relational database or

  • something like that.

  • So it has relationships to other things.

  • So sessions have tracks that they're on, and time slots,

  • and rooms, and speakers.

  • And you have this sort of network of related objects.

  • And that's part of the LOB space.

  • So how are you going to deal with that if you're going to

  • do it on the JavaScript side?

  • So I'm going to propose to you that you're going to need to

  • do queries.

  • And some of them, because you're going to be on mobile

  • devices, and some of them, because you're going to keep

  • looking at them from one view to another, you'll need those

  • queries to be both local and on the server.

  • You'll want to be able to cache data.

  • You'll want to be able to deal with those object graphs I was

  • describing.

  • You'll want to be able to do change tracking, because

  • they're going to be making changes.

  • And you're going to hold them.

  • You're not going to just save them right away.

  • You're not have a save button.

  • And you're going to want to make those things that you're

  • dealing with like sessions and stuff, you want

  • them to have behavior.

  • They're not just data bags.

  • If you just read them in out of the database,

  • they're data bags.

  • But no, if you're going to use them, they're

  • going to have behavior.

  • So you could roll your own framework around this.

  • This is really what ends up happening, whether you call it

  • an official framework or not.

  • And then your ship can run aground.

  • Or you can use Breeze.

  • And that's my commercial.

  • It is open source.

  • It's MIT licensed.

  • It's on GitHub.

  • Enjoy it.

  • So back to this Angular thing.

  • And Angular and Microsoft, and Google and Microsoft, cats and

  • dogs living together, what's that?

  • But yes, it does happen.

  • And not only that, but there is now a in the box Visual

  • Studio is the dot net IDE of choice.

  • And right in the box now, you can get a Breeze Angular

  • template that shows Angular working with Breeze inside of

  • ID, the Visual Studio.

  • As you can see, they're talking about it on a

  • Microsoft address.

  • Not on my site.

  • Of course, I talk about it, too.

  • So it's a two-page app.

  • It's really simple, but it illustrates a lot of

  • capabilities, both of Angular and of Breeze.

  • And this is what it looks like when it runs.

  • And we're going to do a demo of it.

  • And then at the end, I'll show you more about what you can

  • learn more.

  • So--

  • oh my--

  • this is later in the day.

  • No, no, and no.

  • OK.

  • Because we're going to build that app later.

  • So if I were to spin up a new version of the

  • Visual Studio IDE--

  • and there it comes--

  • and I wanted to create a new application, I can do these

  • template kinds of things.

  • And there in the web, ASP MVC, I can do that.

  • And ooh, what's this?

  • Yeah, there's the Angular SPA, right in there.

  • So if I just keep on clicking, I'm going to end up with an

  • application that looks like this.

  • And just to save you the effort of watching this thing

  • running away, to fill it all in, it will end up

  • looking like this.

  • And this is the a ASP.NETMVC4, if you know that world, which

  • has a lot of stuff in it.

  • But the net of it is that your client side application is

  • right here in these JavaScript files and HTML files.

  • And if I run it--

  • and I have to run the right thing, not that one.

  • Get the right keys.

  • It comes up.

  • And I've highlighted some things, because

  • I've been here before.

  • So I have my to-do list, and my never-to-do list, and who

  • knows what that one's going to be.

  • And I could learn--

  • here you see I've learned--

  • no, I'd better learn it again.

  • Learn Angular.

  • Turn it off.

  • By the way, every time I'm going anywhere in here, you'll

  • see that it's saving.

  • See?

  • Save changes.

  • And I could do a bunch of stuff like that.

  • And if I say, oh no, see, there's the

  • validation of all kinds.

  • Yeah, that's not good either.

  • And I can switch over here on the second page

  • and see what I did.

  • And really, the second page is only about logging

  • what's going on.

  • And you can see it saved all these modified things.

  • So it has some idea of change tracking and error handling,

  • and it's all reporting that.

  • And you'll notice that it was initially going remote, but

  • now it's going locally, whatever the heck that means.

  • But that means that it could be kind of fast as I flip back

  • and forth like this, because it's not making

  • a trip to the server.

  • And that's kind of what you want to do.

  • OK?

  • So you can spelunk that to your heart's content.

  • But I'm not going to do that anymore, because we're going

  • to take a trip through Angular and Breeze from

  • what I hope is zero.

  • And I'm also not using Visual Studio anymore.

  • From now on we're going to go with Sublime.

  • So I'm going to create a new one here--

  • NGI create.

  • And I am a really fast typist, as you can tell.

  • Spare you all of that.

  • But this is just a big version of what Brad was showing

  • during the warm up.

  • So there's an NG app and a controller.

  • And there'll be some repeating, and who knows what,

  • but we'll just save that for now.

  • And we'll call that index.html.

  • And trust me, we'll get to know it.

  • Let's create another one.

  • All right, I have to have a controller.

  • You saw that I mentioned the controller.

  • So I'll type really fast again.

  • And there is my controller.

  • And I'm going to just shift this over

  • so I've got a module.

  • I'm stuffing a value in here.

  • But this is really my controller right here.

  • And this is an example of dependency injection.

  • I told you I would use everything in the Angular tool

  • kit, and I will.

  • And so I'm really injecting some stuff in here, and that's

  • the way it is.

  • But I'm going to expose a list of items and a logger and

  • stuff like that.

  • OK.

  • Well, we'll call that app dot JS.

  • All right, so that's kind of like the controller side and

  • the view side.

  • And one of my rules is you never do data access within a

  • controller review model.

  • The controller's job is to manage the view.

  • It is not to go into the intricacies of accessing data.

  • So I always create some kind of other class

  • to wrap around it.

  • That's just good practice.

  • And we'll call that our data context

  • for historical reasons.

  • And, wow, I type fast again.

  • And there it is.

  • And once again, I'm using dependency injection for

  • various reasons to get some stuff in.

  • I won't go into it, because all this code will be made

  • available to you.

  • But let's sort of see what it does.

  • I've got to call that data context dot JS.

  • All right.

  • And if I have done everything right, I will

  • be able to go here.

  • And there's my index HTML.

  • And I guess it worked, because there it is.

  • Unless it's looking at the wrong one.

  • No, that's the right one.

  • So how lucky is that?

  • Worked the first time, thank you very much.

  • We can go home.

  • It's actually not showing very much.

  • I wonder why that is.

  • So let's see.

  • Well, first of all, it's not showing anything, because our

  • controller isn't going to get anything.

  • It would be nice if it did.

  • So let's have our controller--

  • I think it's going to do it--

  • starts with an N. NGA and then [INAUDIBLE].

  • OK.

  • So this would be the kind of thing you would get the items

  • when the controller was instantiated.

  • And what it's going to do is remember, I always go outside.

  • I'm not going to do any data access inside.

  • So I'm going to ask the data context to

  • go get me some items.

  • And because this is the way it is, it's got be

  • asynchronous, right?

  • So this is the grand world of promises.

  • If you don't know what a promise is, let me give you

  • the intuition.

  • I'm going away to go do something, I

  • will give you a promise.

  • When I come back, I'll tell you that I either

  • succeeded or I failed.

  • If I succeeded, I'm going to call your then callback.

  • If I failed, I'm going to call your fail callback.

  • And no matter what happens, I'm going to call

  • this refresh view.

  • Fin finish.

  • So that's kind of the syntax for dealing

  • with this data context.

  • I don't know how it's going to do it, but it's going to give

  • me a promise, and I'm going to react.

  • And when I get it back, I'm going to dump the data into

  • the items so that they'll bind.

  • And if there's an error, I'm going to print it also into

  • the screen.

  • And no matter what happens, I'm going to call this thing

  • called apply, which you do in asynchronous operations in

  • Angular to tell it go refresh yourself.

  • So we put that in.

  • And my bet is that even though we did that, we didn't get

  • anything new, because if we look at the data context,

  • you'll see that the get items was returning nothing.

  • A big nothing.

  • So let's make it return something.

  • We'll blow that away, NGD, and we'll call that get.

  • And lo and behold, now we're going to do something.

  • What are we doing?

  • Well, I'm going to fake the data in here.

  • So I'm going to return some results of two people named

  • Igor Minar and Naomi Black.

  • And one of the great things about promises is you can

  • chain them.

  • So I can do thens and fails before the caller gets his

  • thens and fails.

  • So what I'm going to do when I succeed is I'm

  • going to say yahoo.

  • And then I'm going to return something.

  • And if I go wah, wah, wah, sad face because it failed, that's

  • what I'm going to do.

  • So we'll save that.

  • And let's see if that makes any difference.

  • It did, but I didn't see anything happen here.

  • But at least I got two of something.

  • OK, so I guess it's time to go learn about binding.

  • And there it is, binds to something.

  • Let's replace that with--

  • I'll bet it's the word bind.

  • Yes.

  • So for every item in items, I'm going to show the first

  • name and a space and the last name.

  • Hope it works.

  • Hey, it does.

  • Yahoo.

  • That's binding, a most primitive kind.

  • You've seen it before.

  • OK, that's really nice.

  • But we can't make an application that works

  • entirely from data that we store in the JavaScript.

  • So let's do it the Angular way.

  • Let's use that HTTP thing, which is a kind of primitive

  • way to do Ajax calls.

  • And I'm going to do this whole service name thing.

  • That'll give me a URL.

  • And when I do the get, I'll get back an Angular promise.

  • Now an Angular promise isn't quite like the promises I use

  • in Breeze, which are QJS promises.

  • But Q can convert them for me and it'll return a Q promise.

  • So just ignore the man behind the curtain.

  • And then you get the get succeeded and so forth.

  • And if I do this and I run it again, I get an error message,

  • which is really not what I expected.

  • What line?

  • You know, I did that last time.

  • You can't do that twice, and thank you, audience.

  • You've been most kind.

  • Let's see if that works now.

  • Hey, how about that?

  • I actually just made a trip out to a server somewhere--

  • let's just do it again.

  • And I got speakers from--

  • don't know if you can see that, but--

  • I went out to Sample Service Breeze JS which you can go to,

  • too, because it's just there to serve up some data for you

  • to play with.

  • And that's what I got.

  • And all I did was fish the first name and the

  • last name out of it.

  • So that's good.

  • But look at this.

  • They're in sort of like, whatever order they're sitting

  • in the database.

  • You're not going to get far building an

  • application that way.

  • And so you're off to the races building your listing ship

  • because you'll be building your HHHH HDV handling, all

  • your data access stuff.

  • And that's what people start out by doing.

  • But we're not going to do that, because we're going to

  • do it the Breeze way.

  • So welcome to Breeze, NGD speakers.

  • All right.

  • This time I'm using Breeze, I'm going to create a new

  • instance of this thing called an entity query.

  • It's a query object.

  • And we're going to evolve this query object as we go.

  • And we're going to get it from the speaker's resource.

  • When we get this query, we're going to get it back.

  • And we're going to execute it with something called a

  • manager, which is your gateway to data and

  • also a cache of entities.

  • Everything else is the same, kind of.

  • Just squint.

  • And now if I run it again, it doesn't work.

  • Now why is that?

  • The reason is because I actually can configure Breeze

  • to say, you know what, I don't like--

  • in server land, they're in Pascal case.

  • First name with a big F, and so forth.

  • But in JavaScript, you like to have lower case.

  • So we do some mapping things on the way in,

  • if you tell us to.

  • And I told it to.

  • And so I'll just change that like so.

  • And maybe this time it'll work.

  • Yes.

  • Yahoo.

  • See me do that?

  • So clearly something's a little bit different about the

  • objects that are coming back, what's happening to them.

  • They're actually coming back over the wire as JSON.

  • We take those objects, and we turn them into something

  • called Breeze entities.

  • And we'll see that as it evolves.

  • But for the moment, they're just data bags

  • like everything else.

  • OK.

  • So we still haven't really improved things, because it's

  • still in random order.

  • But we can start to do some interesting

  • things, all client side.

  • Like for example--

  • wrong place--

  • I'm going to evolve this query object that we had here.

  • I'm going to say order by--

  • let's do it first name.

  • See, this is why I don't type.

  • First name, last name.

  • And if this worked, you can see that they

  • are, indeed, sorted.

  • There's Erin, Collen, Dan, Dave.

  • So we got the sort.

  • Now where did that sort take place?

  • It did not take place on the client.

  • It took place on the server on the data tier.

  • It did not take place here.

  • Took place on the data tier.

  • Very important.

  • Well, we could just do it again.

  • Where are you?

  • It's still thinking.

  • You'll see it later.

  • OK.

  • So we've got an order by.

  • What else can we do here?

  • Well, let's see.

  • We probably want to be able to filter it.

  • So let's say, I don't know, the last name.

  • There's a whole vocabulary here.

  • So it could be starts with B. Let's try that.

  • See if that does anything for us.

  • It does.

  • All right?

  • Well, I went too fast there.

  • I'm composing this nifty URL with all that stuff in it.

  • It's kind of an OData query, if you know OData syntax.

  • So I did that.

  • So that happened on the data tier.

  • Let's see.

  • What else could I do there?

  • There was actually a fair amount of data that came back.

  • So I could say I really want to slim it.

  • Well that's almost the same as this syntax here.

  • This is called a projection.

  • See what that does for us.

  • No visible difference there, except if we look at what came

  • over, it's very skinny.

  • First name, last name, first name, last name.

  • None of the rest of the data that came

  • over before is coming.

  • So I can reshape the data on the client side.

  • Or actually, what I do is I shape my instruction on the

  • client side to reshape it, send that

  • instruction to the server.

  • The server on the data tier does the reshaping, and

  • skinnies my data down.

  • I'll get rid of that.

  • OK.

  • But here we are, well, the wrong one.

  • I wanted to get rid of the selects.

  • You can't just sit there plugging Bs in

  • there and Cs and Ds.

  • You got to get what the user wants to do.

  • So let's put a search box in.

  • And where should we put it?

  • We'll put it right here.

  • NGI search.

  • There it is, search.

  • Do a little binding to a thing called search text, which

  • should be in our controller somewhere.

  • And a bunch of other information, and then we'll

  • also see it.

  • So that's nice.

  • Let's go add it to our scope.

  • Our scope keeps getting bigger and bigger as we bind to

  • things, learn to bind to things.

  • All right.

  • So now I said I was bound to a search text.

  • I'm going to give it one.

  • And I'm going to use this other Angular

  • thing called watching.

  • What I'm doing is I'm watching for changes in value.

  • And when I get a change in value, I'm going

  • to call it get items.

  • Right, so every time we type anything in that search box,

  • it's going to get detected, and it's going to get passed

  • down to this get items.

  • That's all well and good, but I'd better pass that

  • information along, because it'll probably

  • need the search text.

  • So I'm going to pass the search

  • text to the data context.

  • That's good, but the data context doesn't

  • know about it yet.

  • So let's extend this query.

  • Let's call it search.

  • OK.

  • So I've got a little reminder here so I don't mess up.

  • Now my get items has got to get a search text parameter.

  • That's going to be the text I'm searching for.

  • And that's good.

  • Got that reminder out of the way.

  • So when the search text comes in, I'm going to evaluate it

  • and trim it and all that other stuff.

  • And if there's any search text left after I take off all the

  • spaces, then I'll say I'm searching for that.

  • But here's the real key.

  • I'm building up the query.

  • I've got to get rid of that [INAUDIBLE], because I'm no

  • longer hard coding B. It starts out as a query.

  • If there's search text, then I will add the filter clause on.

  • If not, I'm just going to go get them all.

  • Let's see if it works.

  • Well, I got that.

  • Let's try--

  • hey, how about that.

  • And I'm kind of tellying you what I'm looking for there.

  • OK.

  • Now we're making some progress here.

  • That's looking closer to an LOB app.

  • As long as I'm searching for last name, why not just search

  • for anything?

  • I got a little bit of search text, why

  • not search for anything?

  • So let's see if we can do that.

  • NGD [INAUDIBLE].

  • And it turns out we can.

  • Otherwise I wouldn't be here.

  • So what you can do is you can create predicates.

  • And you can build things up-- and's and or's and all the

  • kinds of strange conditions.

  • You can build them up.

  • Again, I'm creating the client side query.

  • It's not running against the client.

  • It's being sent to the server.

  • So in this case, I'm looking to say if the first name or

  • last name contains the search text.

  • Did that help things any?

  • Let's find out.

  • What will I know?

  • Well there's B and A. Let's see.

  • There's a BA here and a BA there.

  • Bango Esteban.

  • So it's now working first and last name.

  • Getting closer.

  • Let me catch up with where we're going.

  • The connection here is really great.

  • And apparently my server's working really great, too.

  • So it's going really fast out there.

  • And this is not a realistic speed,

  • certainly, of a mobile app.

  • So I'm going to make this thing slow down by putting a

  • delay of one second in there.

  • And then I'm going to do what I was doing before

  • and execute the query.

  • So I'm just making life a little bit

  • slower and more realistic.

  • And now if we do this, we get an error message.

  • And that's not good.

  • What did I do?

  • Anybody know?

  • Just undo?

  • I could do that.

  • That would be really nice.

  • Let's see if it still works.

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: What did I not get rid of?

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: Oh, here?

  • So you're saying--

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: Oooh, you bad boy.

  • NGD slow.

  • AUDIENCE: I think you need that bracket.

  • WARD BELL: Think I need that bracket, huh?

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: We're going to try this once.

  • And you guys fail.

  • Me, I'm perfect.

  • But no, you failed.

  • I love JavaScript.

  • All right, we're taking that back.

  • Because we don't really need it to be slow, do we?

  • No.

  • I just need it to work.

  • Whew, all right.

  • We're going to pretend it's slow.

  • The whole point of that was damn, just how do I make my

  • application slower?

  • I always want it to.

  • Anyway, the point is if it were slow, we would have some

  • advantage to writing things locally versus going remote,

  • because we're going to be toggling back and forth

  • between pages as I was talking about earlier.

  • So let's see if I can make that work.

  • And we want that to be at the user's option.

  • So up here in the HTML, I am going to say no, stay local.

  • All right, I'm going to put a little check box up there that

  • binds to a stay local property.

  • So when I check it, I'll stay local.

  • Duh.

  • And now it's going to bind to something.

  • So NGA stay local.

  • So there's my stay local variable.

  • And I'm going to watch that guy, too.

  • Because when he fires up, I'm going to go--

  • it's not the first time--

  • I'm going to go to the get items.

  • So no matter what happens, I'm going to end up here.

  • Except that I'm going to need to tell them whether to stay

  • local or not.

  • So I'm going to pass that along to my data context.

  • Now I'm not actually doing it.

  • I'm just telling the data context, hey, if you can go

  • local, I'm telling you to do it.

  • So I guess I better do that.

  • And pray for me, now.

  • Because that was a lot of code.

  • I type really fast.

  • OK.

  • Well, I'll need to get that stay local thing in there,

  • because I need to get that passed through.

  • And I did that in both places, and that's nice.

  • And the other part.

  • So what am I doing?

  • When the stay local comes in, I first of all, make a little

  • text variable so I can log the fact about whether I stayed

  • local or whether I went remote.

  • If I'm staying local, notice the pattern here?

  • I'm just embellishing the query object again.

  • And I'm going to say use the little Breeze thing that tells

  • me to query the cache.

  • That's going to be the same query.

  • Exact same query I would have used to go remote.

  • But I'm going to apply it to the cache of entities I

  • already have.

  • Ignore the man behind the curtain there.

  • Otherwise, I'm just going to go remote.

  • Really what happened is I just decorated it

  • with this little thing.

  • And then I continued on as we did before.

  • And since I'm not doing the delay anymore, because I

  • couldn't make that work, we don't have to do that.

  • OK.

  • Let's see what we got.

  • Let me replay this.

  • And let's go to the network.

  • And have I got XHR?

  • OK.

  • The first time through, I went through and

  • I got all the speakers.

  • And if I do this stuff right, it should be

  • going to get them.

  • And it did.

  • Nice.

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: Yeah.

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: Well that's, of course, nothing.

  • I haven't clicked the stay local yet.

  • My problem was that I was really surprised to see it

  • making network calls.

  • I don't know why.

  • So, duh.

  • Let's clear that out.

  • OK.

  • So now I'm going to go local.

  • Let's see what happens now.

  • No, yes.

  • Why is it going?

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: You know, that's the great thing about

  • JavaScript.

  • Search text.

  • I sent the search text twice.

  • Thank you.

  • You guys were right all along.

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: All right, let's try it again.

  • That time it went.

  • If I go stay local, and now I go like this, yay.

  • No more am I going remotely.

  • See all this locally, locally, locally?

  • So I can do this stuff to my heart's content, and I'm not

  • making any network trips.

  • And that's the point of that one.

  • I talked about object graphs a little bit earlier.

  • And sessions have speakers, and speakers have sessions.

  • And there's this whole stuff that everything's connected.

  • And right now, all I'm doing is getting one thing--

  • speakers, persons.

  • And that's not realistic.

  • Beware the single object demo.

  • So I want to get the sessions that are associated with each

  • of these speakers.

  • But I could get them eagerly or I could get them

  • dynamically as I need.

  • But I'm going to get them eagerly by

  • saying, well, let's see.

  • I want to say expand.

  • And I need to know the navigation path from speakers

  • to sessions.

  • And it's called speaker sessions.

  • So that's what I'm going to do.

  • And I'd like to be able to see that back

  • here in the HTML view.

  • So I think I'm going to replace all of

  • this with NGI expand.

  • How about that?

  • Let's take a second and see what this is.

  • Still the same UL.

  • There's the first name, last name.

  • But it's got an inner repeater--

  • an inner repeater--

  • that's going to get the session information from the

  • related sessions.

  • Pray for me.

  • Error message.

  • Did it again.

  • What did I do?

  • Did that.

  • Well, that's sweet.

  • Hey, it worked, sort of.

  • Great.

  • Maybe the console tells me.

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: Beg your pardon?

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: I'm doing something stupid.

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: You think I have a break point?

  • Well, that would do it.

  • You know, it's a good thing-- can I have

  • you guys in my pocket?

  • There you go.

  • All right, and if I stay local--

  • presumably it stayed local.

  • I've got to leave it there, duh.

  • OK.

  • BA, yes, thank you.

  • So I'm staying local, and it's going really fast, and I'm

  • getting all this stuff.

  • So yes, it did work.

  • You just have to know how to code.

  • OK?

  • You get the idea?

  • Outer one, inner one, and Breeze, simply because of the

  • expand, said every time I get a speaker, no matter how I'm

  • searching for it, I want to get the speaker sessions right

  • along with it.

  • Of course, I could do that on the server.

  • I could do it on the client.

  • But I have a lot of options as I'm developing

  • my client side app.

  • What's my time?

  • I've got how much more?

  • 20 minutes.

  • I've been going very fast.

  • So that's nice.

  • But I'm still dealing with essentially data bags.

  • By the way, you guys can ask me a question, if you like.

  • I'm still dealing with data bags.

  • The stuff that's coming over is speakers--

  • first name, last name, just property stuff.

  • We've seen the query thing.

  • What can we do, though, now that we have

  • the entities in cache?

  • There's more things that you need to do.

  • It's not just about querying.

  • It's about change tracking and validation

  • and stuff like that.

  • So in order to introduce that topic, what I want to do is--

  • oh, by the way, you may have noticed that I

  • never defined speaker.

  • Did you notice that I never went through and described

  • what a speaker was?

  • I didn't say what its properties were?

  • It just had them.

  • That's a feature of Breeze.

  • One of things it's doing is it's getting metadata to

  • describe the model down from the server and it's using it,

  • so that you don't have to code it.

  • If you've seen other systems, you've probably seen where you

  • have to describe the whole model in some kind of a DSL.

  • You can do that also if you want, but you don't have to if

  • everything's going well.

  • So let me create a model class.

  • Remember to save it model JS.

  • And just so I don't forget, we want to make sure

  • that we , load it.

  • Load that script.

  • So let me walk this for you a little bit.

  • Well, it doesn't do much, right?

  • It's the revealing module pattern.

  • It has an initialize method.

  • That's all it's got.

  • And it's got something that it does at the

  • beginning called extend.

  • Here's the initialize.

  • We'll look at that in a second.

  • But first, I just wanted to show you that there's a a

  • person constructor.

  • So if I want to create a constructor, I can.

  • I didn't have to before, but I can.

  • And one reason I might is because I

  • wanted to set some defaults.

  • Like I'm a newbie, if I create a new person.

  • And also, I'd like this person to have some behavior.

  • And I can't send behavior down from the server.

  • But I might like to have a full name property, and I

  • might want to know if it's dirty, if there are changes

  • being made to this person.

  • And this is some Breezy stuff that actually gets that.

  • So I've got that.

  • Now I have to initialize it.

  • And I'm going to go up to--

  • I'm back in the data context, my data access thing.

  • And I'm going to get the model, because I'm using

  • Angular dependency injection here.

  • If I slow down, that may actually work.

  • I won't make a mistake.

  • So I've got the model.

  • And now that I have the model, it had only one method on it,

  • which was an initialize.

  • And basically, I've just got to tell it about the metadata,

  • which I'm going to get from manage.

  • So really what I'm doing here is there's metadata store that

  • describes the model-- all the relationships between all the

  • objects and what they have and stuff like that.

  • And what we've done is we've just evolved it

  • with our own stuff.

  • So you're not restricted to just the data bag coming down

  • from the server.

  • You can make rich objects that have behavior and additional

  • properties and stuff.

  • And all these can be serialized, too, if you want.

  • OK.

  • So we've got that.

  • Let's kind of see how that works.

  • So I'm going to go back to the HTML.

  • And I want to see it.

  • And so to do that, I'm going to use that full name thing--

  • NGI full name.

  • Wow.

  • Let's give ourselves some room here and see what this is

  • really doing.

  • LI, LI, LI, LI.

  • It's a little easier if I make it smaller temporarily.

  • Yep, it's looking good.

  • OK.

  • So forgive me, let's see if I can do it this way.

  • So I'm going to get an input text box and bind it to the

  • first name.

  • I'm going to get another input text box, bind

  • it to the last name.

  • And I'm going to take that full name property that we

  • wrote that we added to the person, I'm going to run that.

  • See if it works.

  • Oh, that's good.

  • So I've got the input text box and the output text box, and

  • I've got the full name property appearing here.

  • So as I make changes, if I call him Bob--

  • oh, notice I must have some indication that it's in a

  • dirty state.

  • So I'm leveraging that as well.

  • And I'm going to do stuff like that, which I know is illegal.

  • Now if I had given this the ability to save, it would be

  • interesting.

  • But I haven't.

  • The thing that's kind of cool here, though, is there's this

  • dirty and all this stuff, but this is not part of the form.

  • So I've just made this change here.

  • And if I go look at--

  • completely, that changed the screen, right?

  • I went off and got [INAUDIBLE] or something like that.

  • And I go back, he's still there.

  • So we're talking about a property, a characteristic of

  • the entity, not of the screen.

  • The screen isn't dirty, the speaker's dirty.

  • Very important distinction.

  • So let's put a break point in here and see what's really

  • going on behind the scenes.

  • And I'm going to put that where it does

  • the get locally thing.

  • Here.

  • And let's do that.

  • And now we're stopped.

  • Give ourselves some room.

  • And let's do a little spelunking of

  • what we've got here.

  • So we have a manager.

  • We know about him.

  • Yay?

  • OK.

  • And we can ask the manager, do you have changes?

  • Tab.

  • Not the Caps Lock.

  • And indeed, we do.

  • I didn't have to save.

  • It's accumulating changes.

  • It'll accumulate changes to anything, any of the entities

  • it's tracking.

  • It can be persons, can be sessions, can be

  • rooms, can be anything.

  • So let's take a look at the first one.

  • And just a reality check.

  • Yeah, there's Bob.

  • Yes, he has a full name.

  • So there's a way to find out.

  • There's an entity aspect property on every entity.

  • And that's your gateway into entity-ness.

  • Normally we try not to pollute the object.

  • It should have the features of a person on it.

  • But every once in a while you want to get under the covers

  • to see, how is Breeze thinking about this thing?

  • And that's what the entity aspect lets you do.

  • So I can ask about the entity state, because that's

  • entity-ness.

  • Yeah, that's right.

  • It's modified.

  • That's what I kind of expected.

  • How about the original values?

  • Oh yeah.

  • So we know that has changed, and what's changed.

  • And I said that it was a--

  • I gave it a really ridiculous name.

  • I wonder if that's a problem.

  • Let's see.

  • Get validation.

  • Because I could always mistype this.

  • Yes, indeed, there is a validation error.

  • The error message is there.

  • So as you make changes to a property, it immediately

  • validates them.

  • You can disable that if you want.

  • But that could be useful if you needed your form to

  • immediately light up with an indication that this had an

  • invalid first name.

  • One thing's for sure, there are several other times.

  • One of the times is save.

  • So this thing will never even try to save.

  • If I try to save this back to the server, it would refuse.

  • It would refuse, because it failed to pass client side

  • validation.

  • Now of course, that's no substitute for server side

  • validation, I just want to warn you.

  • But it gives a better user experience to tell them that

  • they screwed up on the client before you make that long trip

  • to the server.

  • And I can say, you know what?

  • I don't like what's going on here.

  • I want to roll it all back.

  • And if I do that, and now I say let's continue--

  • and just so I don't have another break point, as you

  • guys will take that out--

  • you will notice that Aaron is right back where he was.

  • And of course, I took the break point out, because there

  • was one more thing I wanted to show you.

  • I think what I want to do, is although I could show you

  • that, I want to stop, bring it on home, and

  • then take your questions.

  • So where can you find out more about this Breeze thing?

  • Well, we have a lot of resources on our

  • www.breeze.com site.

  • For example, there's a live tutorial.

  • So you can play with Angular and querying and all kinds of

  • things there right on screen.

  • We have lots of documentation that's sort of a guide.

  • We have an API documentation, just like you would expect,

  • for each of the components.

  • We have a growing set of samples that we've written.

  • We hope to have other people contributing them.

  • And you can learn more about it at www.breezejs.com.

  • And you can follow us on Twitter.

  • And it's 7:33.

  • I am ready for your questions.

  • [APPLAUSE]

  • WARD BELL: Thank you.

  • AUDIENCE: So I noticed that you have all the dot

  • net back end stuff.

  • Do you have the requests that Breeze makes documented such

  • that I could say implement a back end in Rails or Node your

  • Java, or whatever else?

  • WARD BELL: Yes.

  • As a matter of fact, I've got it working against Node.

  • I have a Node example that I would've loved to have trotted

  • out, but I didn't.

  • So that's a pure JavaScript side.

  • We'll be doing a PHP version and a Java version.

  • I don't personally know Rails, but I'm hoping to find

  • somebody who will do that.

  • Yes.

  • Because our principle is that you can have any back

  • end that you want.

  • And if it doesn't, for example, provide

  • metadata, no problem.

  • You can create that on the client side.

  • If it doesn't have the querying stuff, no problem.

  • You can hit it just in any way you want.

  • I make the claim, we're making the samples so

  • that you can see it.

  • But absolutely, we should work with any HTTP server back end.

  • AUDIENCE: OK, cool.

  • AUDIENCE: So does it mean that it works with the REST

  • clients, too?

  • WARD BELL: Would it work with the a REST client?

  • Again, if it serves HTTP, yes.

  • And there are a variety of ways you can do it.

  • There's kind of a hard way the first time.

  • But the whole way of interacting with the back end

  • on the client is there's also a thing called a data service

  • adapter, which allows you to also morph anything on the way

  • in and the way out.

  • We have an Ajax adapter, so you can pull that out and you

  • can short circuit it for testing purposes.

  • So yes, there's a variety of ways in which that could be

  • made to happen.

  • AUDIENCE: How does it handle the cyclic

  • dependency between entities.

  • So for example, parent has children

  • and child has a parent.

  • So usually in the data module, you would [INAUDIBLE].

  • So how does it come to the--

  • WARD BELL: How did it know which?

  • I'm not--

  • AUDIENCE: How does it resolve the cyclic dependency?

  • Basically, like say, for example, NHibernate you say,

  • like parent has children.

  • WARD BELL: Yeah.

  • See, all of that would be on the server side.

  • In other words, the whole language of whether it used

  • NHibernate or any of the other ORMs or something like that,

  • the key question is, how do I communicate those

  • relationships across?

  • And the only standard we know for representing data of this

  • kind is OData.

  • So it doesn't have to be an OData back end.

  • But if your server can describe--

  • and NHibernate can or people who have front

  • ends for it that can--

  • can describe it.

  • Or if it actually is an OData back end, no problem.

  • If it isn't and you can describe it with OData

  • metadata, and we're providing components for you to do so,

  • then it's good.

  • You can just send the stuff from the server.

  • If not, you can describe the metadata and all the

  • relationships in JavaScript with the

  • metadata store object.

  • And actually, you could cache that and serve that.

  • You could keep it locally.

  • So you could make it very fast, if you wanted to.

  • AUDIENCE: So does it maintain the cyclic dependencies?

  • WARD BELL: Oh, yeah, you mean cyclic, like orders have?

  • Customers have orders, order says what's my--

  • yeah, yeah.

  • It breaks all of that.

  • It breaks that chain.

  • It knows all about that.

  • Absolutely.

  • I know what you mean, because you can get into

  • serialization trouble.

  • And virtually any real model has cycles in it.

  • So yeah, yeah, yeah.

  • AUDIENCE: [INAUDIBLE]

  • WARD BELL: You're talking server side stuff now.

  • And so it depends.

  • The answer depends on the server.

  • In this case, I'm using JSON.net and having it break

  • the cycles.

  • But also the way we represent the data, the way we configure

  • it to represent the data, breaks cycles.

WARD BELL: OK, well, I'm going to start.

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

A2 初級

三月 - AngularJS MTV Meetup Livestream。使用Angular和Breeze的CRUD應用。 (March - AngularJS MTV Meetup Livestream: CRUD Apps with Angular and Breeze)

  • 62 6
    101 發佈於 2021 年 01 月 14 日
影片單字