ASP.NET Community Standup - Oct 9, 2018 - The Blazor Show!
And 3 2 1. Yes. I'm starting. Well. Live. From. Redmond, and wherever. John lives and wherever Steve lives. Yes. Very descriptive thank you very much and our hope is that this week this. Will be the best technical. Show, in terms of production and no gremlins, and audio and, switching. And all the things that we've, ever done I spent an hour in this room earlier today I put a little bits of tape here without numbers on them so everyone's in sitting in the right spot we've got a new screen set up here so we can see our guests, and they can see us can. You say hello John I can see hello, hopefully. Their levels are good the, one thing I found with you I've just realized oh no I have the chat open here so I can talk to people as well so it doesn't like people. Can. See us as well which is good well looks why. Are we here today why, do I have these fine gentlemen on, my left it's because, oh and, of course it's Steve saari on the on, the road that. Way create it right next week thank you, because. We're here to talk about Blazer yet again the only thing that anyone ever really wants to talk about this. Yeah. We thought we bring the back as you have a new release we, do ok. 0.66. Is live without last week with. Lots of new goodies for people to try out no goodies, ok. You gonna show us some stuff for weekend the John deal at the community this week when I take John's I do I, do love the community this week. And. How, about we switch to yeah. I know here just a second, community or. We could just watch Steve drinkies coffee there's a coffee or tea Steve T. Is. T versus, England if it whining. This. Tesco, or something tasket England. Does. It do you see my screen you do we are all good. Ok, so this is a short, small, collection, of just Blazer links for this week I have some other ones but this is, blazer specific. This week so, one. Thing I looked at was. It's. Kind of cool people are kind of lighting up different, things that have been in the dotnet ecosystem. And lighting the upon blazer so this one's an interesting, just Sarah log. You. Know we've seen this in asp, net core for a while and here lighting up in laser, so the idea is like you, know I'm having structured data in your browser console um, so I thought, that was kind of cool so. This repo, here log syncs. Browser console. Next. One here, this. One is cool so my hair has set up he, needed to do medical imaging, and you.
Our Surveys we asked people you know how many of you were which, of these hosting models which one would you like to use you. Know the. Vast majority of course are very interested in client-side and that is still the goal but. About 60%, of Blazer users said you know that server-side, model that's all I need in fact that's what I want I like the idea of having the my code living, on the server, I like the control I like that the client can be thinner it doesn't have the dependency, on on having. A full web assembly capabilities, in the client that's that's actually really compelling, to me so, we've decided to go ahead and move forward with shipping that so, server side blazer is going to get integrated into, ACE the next version of asp.net core, which is shipping with NIC or 300 and we decided to give it a new name, try and distinguish it a little bit from the the webassembly support, we're calling it Razer components. So, server-side laser is going to become Razer components, in asp.net, core, 3.0. Which. Will, be shipping you know sometime, sometime, next year I think we said that we would have the first preview bits of dotnet course Ryo going out in early 2019. So, we're pumped about that because blaze is really made up of two parts right like you have the component model and then, you've got this web assembly, paste dotnet, runtime that really enables the client-side scenarios, the component, model is flexible it could run on the browser you can run on the server and. In fact we've made it so that if you want, to start on the server and then switch to the client you can do that by just basically, changing a line of code assuming you've written your components, in a way that are abstracted, from server, specific, things so. We can make progress on, the component model and the, web, assembly based runtime, that will continue experimental, for a little while longer we are still working very hard on that we will continue to of course to the. Ship support for the the client-side model on top of web assembly we think of the, server side support as a as, a path to, get to that client it enables us to ship a big chunk of Blaser as fast as we can while we continue to work on getting the runtime to be fast to, be small to have, good hitter. At build times all those things are things that we're working on in parallel yeah and as others have pointed out there's also some, scenarios, it's just a better so possibly, by the server-side scenario than the client sites that are used there are things that you can do on the server that it just feels so natural now like you can go ahead and go right to the database if you want to you can use any dotnet library that you want on the server because it's just net core you. Can de bugging just works as it normally does because it's just dotnet, core running on the server there's a lot of things that are that are very natural about that like any type of things I think as I said of trade-offs like if something's running in a different place from somewhere else you get a different set of stuff you can do different set of capabilities and that's, traded off against things that you can't do commonly, so I think the way forward is both models and like the one that we can commit to right now is the server-side model because we don't need a runtime for that we've already got one and, so we're.
Working Through right now what it looks like to get that into the server side es that call we have today we already have a server-side model we have raised, the pages we have raised a very have, stuff and so we're working through the process of like what does it mean to introduce a third thing, we have use pages, and now we have components and how they will work together and all that type of stuff and the good news is if you're using any, part of blazer right today the, component, model and the tools are going to become baked right, time they're gonna become done and stable and that kind of thing so if you're using blazer in any way this is really going to help you out even, if you're not using the server-side model yes. We're. Excited about that and, I think we want to show you a little bit about what's in the latest release great. Six. Let's, flip over let's flip over to me and I'm gonna have I'm gonna have the world's least. Impressive demo here to start off but this is a as. A general, this is going to be a gentle, introduction, to, templated, components, so, if you haven't read the haven't. Read the the blog post or haven't seen anything about this this is hello world so we've, got the standard blazer template, here we've got the little counter you click it it counts, it's great everybody's, seen it before we're. Going to turn this into a template component, and we're going to very quickly sort, of just demonstrate, what, does it mean to be a template, component, I am, going to grab all of this content, here so here's the the functional. Wheels sorry. Are we all seeing Y in the screen right now. I'm. Gonna uncopyable. Coming. Through are you sure to counter yeah, I heard it's on the live screen I heard no AV issue it is coming through on YouTube so, it's not, the. Other remote attendees, you need to go out to live dot asp.net and, we're sorry the folks on the team's goal here you don't get to see it you have live you have to go and watch it like everyone else so I'm gonna grab all of this content from the counter and I'm, gonna stick this in this template encounter component. And then, I'm going to replace some, of the functionality, here with this template a counter. So. Here's this component. Can use it and then if we come back here you'll see I've got these two render fragment properties, you. Might be familiar with using render fragment with the name child content, before that was like a magic name it's sort of the implicit. Whatever, is in the middle of your component, would show up in child content now, you have the ability to define, multiple. Render, fragments, and. Render fragments to take. And, use these so let's I've defined these two I did this ahead of time just to save just to save typing but, let's go ahead and use them so I'm going to replace this, with, the counter, content so this is the display. Of the counter and so. To do that I'm, going to I'm going to do at counter, content, in case this is a funk and I'm gonna invoke it and then, I'm gonna pass in the current count so, I'm, gonna run this. Fragment, of rendering that's in the, to encounter content, and I'm going to pass it the current count and then, what I can do is I can come over here to the usage, of the component, and you. Can see that under here what did I call this I called this counter content, I have, this counter content, element and then. I can paste that inside here and what. You're going to see is that. If you're inside this counter content block you have this magic, parameter, called context. And this. Is sort of defined implicitly. If. You want to use so this is this is that integer that's going to be passed in here if you hover over that you can see that it's an integer so the, current count from here is going. To be passed into this when. This renders and if I want to change the name of that I can do that as well so if I say like current. Count notice. That went red right, away I can. Take this back and I can put this put, this here if I prefer a different, variable name or something like that and that's all fine and. Then I've also got this button content, so let's let's. Take this out of here and we'll put the button. Content, and the way that you use these render, fragments, is you just effectively. Return. Them from Razer anytime, anytime in Razer you see like at foo you, can think of this as like well, that's not a good example but you can think of this as just like returning, something to let it be to, be rendered so if you've got a render, fragment of integer it's a function that you call if you've got a regular old render fragment you just return it and then, let's come over here and let's fill.
That In so I think I called this button. Content, and let's. Ooh that, was gross. Let's. Give. This. You know I said hi. Stand. Up. And. If we run this you'll see that my my. Stuff is filled in here and it's, I've passed these two fragments into, this, other component, so the, way that you use this or sort, of what I've accomplished here I know this is kind of a hello world example is you, can build components, that are very very. Reusable because. You don't have to specify all the content, inside these components, you can specify the content, where. They're used we had a limited form of this before but, now we're taking it much much further we're making it much much richer we. Had like child content, before we have child content, a special, car ammeter and now you can have multiple parameters, they can have names they, can have parameters, they can be generic. So. This is kind of the basic example for something more sophisticated I'm, going to come over here to the flight, finder, and I. Have enhanced, you, may have seen this demo before a flight fan there is a sample, that we've had around for a while you. Can do a search and you, can see that I find some flights I can, sort, these. Two are already sorted by both those things I can add them to this list I can remove them from this list it's pretty great. Pretty useful we. Use this to plan all of all of Steve's travel to come visit us, but. You can see that I've enhanced, this now and. I've added the new tab to this I've added the search for car rentals so. If we put in I think Steve's coming later, this month so, you know I'm gonna pick I'm gonna pick the date so I'll let him know later I'm. Gonna actually you, know it'd be great if he could leave. Tomorrow. So. If I search I'll, get some cars and then, I can add them to this short. List and you'll see that if I if I move back and forth these are all you, know part of the same list, here so, what, I have created here this, is this is kind of standard stuff. But, what I have created here is an opportunity for us to learn about templated. Components, with, generics. So. If we come over to this. This. Code which is the flight finder code you see that I've got these two high-level pages. So this is like the main page this is where the flight search happens, and you. See the flight search results, and then I've got this car rental page which is where you see the car rentals and the. Car rental results, now, I want to dig into, these I'm going to dig into this a little bit and we're going to be spending our time inside, this car rental search, results so, you remember, at the top we have the search area at the, bottom we have the results area and at, the right to hand side we have the short list or like the list of things that are being considered, we're, going to be spending our time inside, this results, control. Air, component, and see what we can do with that so, I've got a car, rental search results, and, I've. Got a. Flight. Search results, here and if. You pull these out and look at them side-by-side and. It may be a little hard to do this with the window, size and the font size you'll. You'll start to notice that these two things are really kind of the same I mean, they have the same markup, they both take a list of itineraries. They, both sort the list and then they both display. Some kind of component, in the body, they. Really are kind of the same so. This is a good opportunity for us to use generics, and template components, to sort of like, extract.
The Common features of these and make, a component, that's a little bit more reusable, so. What I'm going to do is I am going to grab all the content, here and we're, going to just sort of do this live so. I have got another component, here that I already created. That. Doesn't have it doesn't really have anything in it and I, am going to start us off by doing, this. So. I have this add type per annum directive, and, we'll say t results. Because these are search results, so. Now you see I've declared, a generic type parameter, and I can start filling, this in places so. I'm going to uncomment this code this is my this. Is my little sorting. Helper here I'm going to uncomment this code and, you, can see I've already got T. Result here and that's. Going to light up and that, that works I've now, got a generic in here so that's like defining a genera, generic, parameter, on the class exactly, look for the component exactly so, I'm going to grab now. The. Itineraries, and. I'm. Going to bring that over here because we're going to need to pass. In the results and then. The other thing I'm going to pass in is because, you notice that the way that these are sorted, these, are sort of in a way that's specific to flight itineraries. So, we're going to need a generic, way to sort this and I've already done sort of the library work for this I've already done all the uninteresting. Things I'm just going to show you the Blazer part, of it so. I'm going to declare a parameter, and it's. Going to be an eye read-only, list of. String. Display. Text. Too, I compare, ER of. T. Results, and. Then. The this will be our sorts. Options. We're. Going to pass in the options. For sorting, so. We can sort in a generic way and then, this, should. Be T result because. It's not going to be hard-coded anymore. So. What, else do I need well I noticed, that I've got flight. Search result, here and I want to I want to basically mix up the last demo with this demo I need to pass in the thing that I want to render here, so. I'm going to have this list of sorted itineraries, which I'll going. To change this right now so this should be sorts, of, items. For, itineraries. Get. Spell. Should. Be sort of itineraries, so you can see that this is T result so I need something here that can render a T result, well, I can, combine, templates. And generics. So, I'll have a render fragment, of Te, results, result, and we'll. Call this like results. Content. So. That I can pass that in and then, to use this it's just like I did before this. Is going to be, result. Content, and I, just pass in the item, so. I've sort of like abstracted. Out this loop right now. There's one other change that I have to make here is I. Have to deal with the fact that this. Is hard-coded to use the flight itinerary, sort instead of these sort options so, I'm just going to do that real quick. And. Sorts, can. Sort, options, that count I always, get this confused, between count, and length, and I always want to use length for I read only list which is the best interface and dotnet and. Then, we're going to put. This option, inside the loop and use. Our variable, here and then, instead of using the enum value we're just going to use the index because. That would cause problems with generics to actually use the enum value and then, this will be the text that we get from sort options oh. I. Forgot my @ that's why it's not completing. Its.
Play Text so, now we're going to render all of the sort options, in this, options drop-down so somebody can pass in the sort options somebody, can pass in a result content, to render from here and if you look at this you see that there's no there's. No flight options. There's, no flights anything in here where, are we complaining about here does. Not contain, a definition. For compare oh because. I didn't give it a name. Does. Not contain any flight, anything, or any car anything it's become totally. Totally, generic at this point and if I give this a bill this should build I haven't, used it yet we'll do that next. Okay. Good so we've done a build so, let's come over here and let's use it so, inside, of here instead of flight search results, I'm going to plug in my generic, search results, now I still need to pass in the itineraries. So. In this case it's a flight search results, so I'll pass those in and. Then I need to pass in the sort options, now, I mentioned that I've done I had done this earlier so I've already kind of stashed. These away somewhere. Out of the way. Married. Sort, of get sort options so, I already stashed these away somewhere else and. Then inside the body of this we're going to need to specify that result content, and the. Result content, if. We. Look back at this search, results was just this guy so. I'll grab that. Put. That here inside, result content. And. Then. Remember. We had talked about the parameter, names for these templates before this. Parameter name by default will not be item, it, will be context. So we could either use context. Here or we could rename it I, like, I like item a little bit better so we'll put item here and then this is coming from our appstate container so that's a different, variable so. Now I can get rid of this because, we're done with that and. What, if I got. A little bit of an error here what to check that out I think, that this needs to be. An. Action, so, just, have to do this. Does, not take zero arguments. Okay. Hold on a sec it's an action so it takes an argument immaculate. A right yeah. This. Kind, of things kind of hard yeah, it, is a little hard no. Disrespect, intended yeah. Just. See sharp that's making us so, I have the wrong I had the wrong function name because it's called different things in different places so, I'm basically I'm passing to this component, I'm going, to pass in you. Know for. Whatever item you have add that item to the itinerary so, if we run this now. This. Should all just work and, you. Should see the flight page the. Flight search, page in search results page come up sort. Of as it is so. Remember, this is the same thing we saw before and I. Can do a search and I've. Got sorting. Here these are already sorted in the same order for both so let's see, if we can get a different one but, I've got I've got my sorting. Here these are also already in order by shortest, I've, got my sort here I've got my add to item at, the shortlist and I've got all these little things here that all work the same and I've made the code for this this, grey window down here this bottom portion is all completely generic.
Marks. Are both car, rentals or four flights yeah yeah. So. That's that's kind of like a an, application, of. The. You. Integrating. That into your application development. But you can sort, of imagine them taking that feature and building, out like component, libraries mmm that have generic. Functionality, that then can be reused in a variety of applications not like you know tailored. To deter just one yeah, this is kind of a this is kind of I think Steve and I said, that this was an intermediate, usage of feature like this so we're kind of diving into the deep end or a little bit but features, like templated components, and generics together are really, a little, more targeted, at authoring, controls, and authoring reusable, little bits of functionality. The, really neat part of this that makes this go, is kind of how generics, interact with the compiler. So. Something else that you can do with this if you're if you don't you know. If. You use generics in c-sharp before you know that sometimes the type can be inferred and some the type has to be specified. Well we actually let you specify. The type. Because. Sometimes. It can be inferred and sometimes it can't be so, when you write a component, that is a generic type like we did we, add an extra parameter. Here so. That you can specify the type if you need to and that matches the name of the type, parameter to the for the component yeah so this parameter name is derived from the type name of the of the component, and, that won't be needed all the time but it will, be needed and I think in some complicated, cases there's. Some things that don't infer. Super, super well but. That's that's kind of an overview of this so we've got a couple features that are working together here we've got generics. We've got multiple. Child content, parameters we've, got child content, parameters, with parameters. And. All these things put together to, make it possible for you to write things that are a little more high-level and a little more reusable. Super. Cool I want to relay some comments yeah I think from the viewers um, a couple of folks, commenting. About having. The code in the component file we get this yeah there's always you know some people who-who who. Made that comment I've with, medical ear that you can put the code for, a component in a different file. I think it's an inheritance, model currently is so so the, answer that we would give and we have been giving is and we're working on it yes so what. We hope will work and what we hope people will like is we. Hope to enable, you to use partial classes for this okay we, think people are familiar with partial classes they write pretty well the, reason why we haven't done it yet is we, have to get the tooling side of it sorted out yes, yes, there's.
Some There's some artifacts, of the way tooling works that don't work well with, with. Partial, classes and we're, working on it we're, aware of the feedback and we're working yep so it's. There's no right or wrong some, folks like to have it in the one file it's very common to see that in other component, based UI frameworks especially from the spar world it's very common to have it together from. The dotnet side of the world we seem to see a lot of more folks prefer to have them separated, and there seems to be some connotation, with bad practice, or something with them together I'm, not gonna jump on either bandwagon, do whatever makes you happy but just one. Is not inherently correct, the other one who you will be able to do either it's fine but for the folks that want to do it today yes if there is an inheritance mom yes and the way you do it is like if you had countered OCS HTML, you can define a counter CSS HTML, CS and to, find a counter base, class that derives, from blazer component and then, in your CSS. HTML file you say inherits, from that. Base component, and then you can put all of your your, code like your your event handling methods your, on indeed whatever in the the base class and that that allows to the, majority of the code that would normally live in the app functions section to move into a separate file so you can't do it today yeah like Ryan said though that we would like to do that with the class different idea yeah it, kind of speaks to the fact that that blazer is a big, topic it has, been operating in this experimental, mode like for as much as possible we've, been trying to use, the available. Expect extensibility, points, that we have the. Available tooling extensibility, points that we have to. Enable as much of the experience as we can without really going too deep into like making actual runtime feature changes as, we move into this 300, wave like actually productizing, razor components. And making that part of the the. A spec core experience we, do of course plan, to start doing those things and there'll be a big tooling. Train. That we'll be able to make some of these underlying changes I mean they, we could have built the partial. Class support that just wouldn't have worked well and bs right.
I Turned it off because my machine is absolutely dying when it's on but anyway I am here, to. Do that so. It. Is a form of rewriting okay, so you. Need to pre-process, the CSS, to go through change all the classes selectors. To add a special. Like gooood, prefix to it and then, you put the grid on all of the HTML attributes and the right stuff matches up it seems so anti how, CSS, should, be done but i can understand i mean they've got two tensions working against each other here which is you want this isolation. This componentization, of, UI but. You want to use this cascading, based system with inheritance rules and specificity. Rules in order to facilitate it you just kind of have to get well we can't have both of those things so let's just carve out a part of the world with a good and that's. What we'll use is i i've. Never looked closely at how they do it and then on that side of the fence and i i'm interested, in how you have a component that can inherit some. Aspects, of the pager that's in or the or the component that it's in but also habits only things that these aren't unique problems, that we've had this you, know issue with doing web base you i composition, forever likey and there's been lots of different ways of trying to solve this most, CMS's, have some type of way most control frameworks, often, come with a like. A manager, control that, like it's the marshall marshall are on the page of what CSS gets loaded when and how they compose together and I've seen some patterns in the CSS community, to where people come up with like mini frameworks, and are frameworks and more like rules to follow just structure CSS in a way that composers well together and, then you've got things like bootstrap and stuff like that as well which tries to give you things, that you can just lay on top but it's an interesting problem I guess the short answer is we don't. Have a, panacea, for you just yet we don't. And I don't know you know if I'd say it's particularly high on our backlog right now I think we this may be one of those areas where we you, know take, a similar strategy to what the react community has done which is like we'll provide the base component model, framework. And then see what the community comes up with around, CSS. Encapsulation, but as the bare minimum like I think we would get to the point like you said where you'd have your component, library. You can put components. In it with static files and they, all get embedded into the same DLL thus package but then on the consumption, side when you bring that in the question is great I have the types, that's easy as to.net path but, like how do the static files get served we have a pattern, in a spinet core where we can find. Them in the ref like a web part what do we call the application, parts type thing and then the static file handler can find those or something like to be I'm assuming we could do stuff like that we have some basic patterns today like see if you want to talk a little bit about how the Blazer. Component, libraries surface, no static assets that get embedded in them yeah. So with, a blazer component library we use, some NS bill metadata, to, identify. Which files are the static assets that you want to make possible to serve and so, as part of the build process we, will drop those static files in a. Location, that the. Middleware, can find at, runtime so, basically. It does just work without you having to do anything okay I'm and if you want to customize it you need to get into the msbuild side of that but, they don't remain I guess the key there is that on the consumption side the static files don't remain componentize. They actually get exploded back out into the project in unknown location, so they can be served yeah. You don't see it because it only appears in your bin directory in fact advising, but it is there for the runtime. Like. When you build the component, library the it's not like they're embedded aesthetic, resources. They're just treated as content in like package, gets gets, packaged up we changed from one design. To the other and I can't even remember which one we ended up but whichever is the better design that's what.
Steve. Does have another demo - that's, why we. Have we want to show we want to show some things that team is working on okay well, I. Just wanted to make sure that we I got these comments, as they went through oh yeah that's why we fine for now and let's jump. Took a steam, you've got a demo for us is that right yeah, all right then let's turn. My camera off and start showing my screen. Now. Tell me when you see the counter yeah good. You. Don't say okay good all right then so. Let's. Talk a little bit about some. Of the things we're trying to do in the point 7 release which obviously hasn't come out yet, but. One of the ideas we've got with this release is to, build on the. Work that Ryan's done on temperature components, and make. It easier to build, more. Interesting, high-level components, the sort of thing that you'll remember from all of the your our tool kits things. Like grids. And, tabs. And, you. Know. Carousels. Or whatever all these kinds of controls. That people are used to making, sure that they can be modeled really well as laser, components. Okay, so temperature, components is part of that another, part of it that we haven't addressed. Prior. To now is the ability for components, to communicate, based on, ancestor. And descendant, relationships, so. You might want to say okay, for all of the components, within this particular. Subtree. Of my UI I want them all to share a certain bit of data or, you might want to say something like okay, I've got a. Grid. Row component, and it needs to be able to find which grid it's inside in order to be able to interact, with that in, various ways does that make sense well. Good. All right so let me show you a couple of demos, of things. That we are freshly working, on this is very very fresh indeed it's not merged into master yet, it. Was literally, implemented, today so. We, will just hope, that it all works out. Okay. Sorry. One. Of the highlights of watching, you steam. Is that you show us stuff that you build 20 minutes ago and it's amazing and polished and we all want. All. Right so. You. Can see the counter component right you've all seen this before it's, got this blue bar and we click the account goes up all right so, let's say we don't want this button to be blue necessarily. In fact we don't know what color we want it to be yet we want to have a sort of theming system built. Into our application so. That we can define themes in one location and all, the components, within a certain part of our UI we'll be able to pick up that theme information, okay, so. Why. Is our button blue right, now well it's because of this CSS, class yeah, but in primary, so that's something defined, in bootstrap for and that makes things blue by, default okay but I want to have a way of changing that and I'm, gonna do so by defining a class called. Theme info, just enormous eShop class with this string property called, button class on, am okay, and I, want to have a way of providing, instances. Of this to. A particular. Subset. Of my user interface and. I can do that using a new feature which. Is called the provider, component. And you can put a provider in any component, you want and in. This little demo I'm going to put it into my layout, because in Blazer layouts. Our components, just like pages, are components just like components, are components everything is components, okay so, here we are inside the main layout and, I'm going to instantiate. One. Of these theme, infos okay and I'm, going to say that the button plus on this theme is button. Success, all. Right so, to provide. That I can choose which part of the UI I want to provide it to and I'm, going to provide it to whatever is the body part of the page I can put this wherever I want really but I'm going to put a provider, here and I'm gonna say the value we are providing, is the.
Theme, Okay. And. Let's. Get the nesting, correctly. All. Right so, if I recompile, my application, now and then I go back into a browser and reload let's see what effect that has on this blue button the. Effect it has is. Nothing. At all why is that because. I have, not been consuming, the value that's, been provided yet, so let's say we want to consume, that value and, we're going to go over to the counter, component, now and I'm, going to consume, it as a, parameter so. If you've used Blaser before you'll be familiar with they. Are something that gets passed into your component and the value can change and, value. Can be whatever type you want and so on so, in this case I'm going to be taking, a theme in fur and I, can give it any name I want I'm gonna call it current theme because that obviously makes sense and we'll. Put to get and set on that okay now, with. This defined, as it is this. Is just a normal parameter, which means it's part of the contract between, this component, and its, immediate parent but. That's not what we want in this case we don't want this value, to come from, the immediate parent necessarily. We want it to come from any ancestor, that can provide that value so, I'm going to use this new. Flag. Called from tree and the. Naming here by the way is very likely to change so I've sort, of made this up without really thinking it through very, carefully we're, going to in veritably, have meetings and search and decide what, the right names for these things are really big gonna be so it might not be called. From tree it might be call something like from ancestor, or it might be something like cascades. Equals, true or something I don't know but let's not worry about that right now the, logically. We're just getting this parameter from somewhere, in the ancestry. Okay, and since, we're doing that I can now say instead of displaying button parameter, button, primary, I'm going, to image, current. Theme, button. Class okay. Hopefully. The. Value, will be provided, further up the tree by the provider component, and then it can be picked up by any descendants, that wants to get, the current theme info so. Now when I reload, my browser instead, of the blue button you'll see we've got a green button because. That's what the theme information. Declares, and if, I wanted to change that and of course I can go back to whichever. Part of the UI, subtree. Is receiving. That theme and I can change what gets passed to it let's say button danger, that's, another one of the built-in bootstrap. Four styles, so, now when I reload instead, of green I'm, going to get red, okay. So, this is a very simple, way of using, providers. To. Supply. Data, down. An entire subtree, does. That make sense yeah. It actually. I'm gonna say something sacrilege, I'm super, sorry I'm. Gonna apologize ahead, of time it looks like themes in system web in web forms yeah. What except, it's way more general, because it's not just for themes you know. It. Seems like there's, gonna be a class of person, who is going to look at this and say it looks like polymer, it looks like web components, these things are all very important.
There's. The overloading, of words component, but then there's also the old heads that, are gonna say this looks like web forms and, it seems like that's a good thing it is the best concepts, from all the different things yeah. And. I didn't at all mean that in with. Any connotation, whatsoever, I was thinking back to I mean I think nearly every UI platform. Framework, eventually. Has some type of way to do theming. And to. To. Steve's point this isn't, specifically. About theming it's just about the form I understand it's basically a way of tunneling. Values, down the component, tree right, yeah yeah, that's right theme is a common example so this, feature in, Blazer is very similar to the. Inject. Feature, from, view and it's very similar to what, used to be called context, in react so you, know all these UI frameworks do essentially, share the same concept, and, theming. Is basically the hello world example that, everybody uses when. Tunneling. Data from one place to another that's why I've shown you that I will, show you a more interesting example now. So. It's. Not just about passing, data, but it's also about enabling. Collaboration. Between components, and, to. Give you a concrete. Example of that let's think about tabs, right. So tabs don't just live on their own they live as part of a family a little group of tabs all together and if. You are representing. That as components you probably have something like a tab set component, and inside there you've got a bunch of tabs okay. And these need to collaborate because when you went click on one of those tabs we, have to have a way of telling the tab set to, unselect, whatever, was the selected thing before and select, the new thing and change what, is being displayed so. You need this form of collaboration, and it's. Based on ancestor. Descendant relationships. Because she could have multiple, tab sets in different parts of your application and you need each tab to know which tab set it's part of now. You could do this in the past with blazer by manually, wiring everything up but the point of this. Inherited. Parameters, or three parameters, whatever we call it is that, the wiring, can be done by, the person who are authors the controls, the, components, not, by the person, who is consuming them, so, if you're building a UI toolkit, you can use this feature to make your components, work, together and the person uses them without average think about that so, I have. About, an hour ago made. A very very simplistic. Version, of tab sets and let's. Just use that now and then I'll show you how it works so, here on my home page I'm going to add a tab set okay and inside that will put a tab and we, can give it a title first. Tab, and we'll, put some content. Inside there let's, say this is the, first. Tab. And. It. Is. The best tab. Okay and then we'll have another tab. Title. Equals, let's. Say counter, and just to show you input arbitrary, things in there I'm gonna put a counter component, inside that tab alright so. Let's just show you this working and then I'll show you how it works and how it does this collaboration, using, three parameters, so. Back. Over here you'll see we've got these tabs now that. We've just added and they do actually work so I can switch between first. And counter, like you'd expect and the, counter does actually work because you know it's just a normal component, and it's picked, up the themes and everything's working like it, should okay, but how does it work so, how, do, the components. Talk, to each other well. If I go into this. Implementation. Of tab set here you, will see that it's. Not completely trivial I'm not I'm. Not going to pretend that it is it's 51 lines, and not, all of it is totally obvious but, the important, bit that, you need to understand, is that. We. Are using these, providers, to enable collaboration between components, so, here the, tab set just, before it renders its own child content, it says I'm, going to provide. Myself to, all the children so, any of the descendants, that want to find which tab set they are inside can, just say oh I want to receive a tab set as a parameter and they're, going to get the tab set that they are inside, so. If I go over onto the tab you, will see that, here and we I've, got this three parameter, that's, of type tab set called, ancestor, tab set and so, the tab can discover what tab set it's inside it, doesn't have to be be immediate parent it can be any ancestor.
And Then, we can do things like when. We get created, will register. Ourselves, when we get disposed, will unregister, ourselves, now, there is some weird stuff going on here like all these weird casts, you can just ignore that. Just. Pretend. This. Is the workaround for one of those same issues that ryan alluded to earlier just, pretend you don't see that because, that will go away eventually. Anyway. The point is that components, can discover each other based on ancestor relationships, and then, call methods on each other and that allows you to do this sort of collaboration, and this. Sort. Of form of building. Components. Declaratively. Well. It's not just declarative, it's also procedural, I want to show you a thing that might not be obvious that you could even do it so, let's say I want to add a third tab yes I'm just going to copy paste that and I'll. Call it third tab. Tab. Good, um but. I don't always want to display this third tab I want to display it conditionally, based on some flag now, with, most, traditional UI frameworks, you would have to have some special sort of api's, to say add tab and remove tab, and that sort of thing but with this model I don't have to do any of that I can, just have a bull, value. Will, show. Third, tab, okay, and then, based on that I could just use an if statement if sure third tab we're, going to show that and if. Not, then we won't and then to toggle that I'll put a checkbox in here input. Type. Equals. Checkbox. I'm going to bind that to the, sure, third, tab, thing like that okay. So, now back, in the UI when I reload we should see that we've got the three tabs no we have got three tubs yet because I haven't checked this checkbox when, I check it a third tab will appear I can go and show it I can go back I can uncheck it the top disappears. I just. Have to stop here for a second say. My. Brain hurts. This. Style, of this. Modern, component-based. Style, for, UI frameworks. That is both. Declarative. And imperative. Still. Really does my head, the. Fact that you could write that I mean I grew up in the world of these things being much more declarative and, data.
Binding Drive everything because it was all server based right and but, even in winforms. WPF you, would have a strong data binding system and you would rely and I know if I properly changed all those type of things this, world were I can because things are really a 'td right I'm, assuming this is how this works like the fact that that checkbox Wayne it's just an automatic it's, just like mvvm style binding, right so as soon as you make a change then, it's it's. Just. Because. Nothing, declared, those things is like bind as a binding, it's like it's just that I'm using that property in, an expression like an if statement that's, not a binding of the declaration in the traditional, sense of the word the way that we kind of were all brought up with binding systems or you have a binding, expression, which is a different, thing like. In example, there's a binding expression, in a spin air there's a binding expression, the frameworks take the code away from Wright they take and you can't do everything in a binding expression that you can do in a normal code block in here, it's just code and like this is this is incredible mix of declaration, and, imperative. Flow and it, it, just it's so deceptively, simple when he wrote that code I was like why can't work is, doing it like you just wrapped it a new statement I'd have to duck don't I have to declare like a boolean, thing with it a binding, thing and like a to Wavelab, no it's just it's just way sorry I just it. Still does every time I see it please all right yeah, so. The fact that we can do this really is the, combination. Of the, temperatures, components, that's an incentive, part of this because a tab set is a temperature component, a tab is also a templates a component, and it's. A, combination. Of the generic, components, as well that. Might not be obvious but, if. I go back over here this. Provider, is a provider of tea if you can read incredibly, small tax, see that that's what that is so, the value we're providing there, is generic, as well which means that we can, differentiate different, types of nulls and things like that that wouldn't be possible if it wasn't a generic, component, and, and. Finally it's these ability. To do tree parameters, that allow, you to pass. Stuff up and down the. Ancestry. So, the combination, of those three things allows us to model some, really interesting bits of the UI and quite nice natural ways. So. That's, that. So in terms of like. The. Same sort of thing when I was looking I was working on something and I had to like I was. Looking, for how do I notify, it to change and how do I notify an update and it just magically does it right and so is it kind of almost like a react. Style way of thinking where if I set a property, on somewhere. On the tree it like smartly, figures out what to re-render and that kind of thing yeah. It's very much a react style of things it's, so much a react style of things that. You. It, doesn't it's not magic, when. You change your properties you, sometimes, have to notify the system, that you've done that because it's, not sort, of magically, inspecting, the state of all your Donette objects and observing if they change in some way so. If you change them outside, the, flow of blazes, normal event. Model then, Blaser doesn't know that you've done that and that's why you have this stay has changed method that, you have to call if you're if you're working outside the event model and, the main Steve the main case where that comes up is async right are there other are there other cases where that comes up a lot yeah. Another, case will be collaboration, between components so let, me show you how, what, tabs set is doing. You'll. See that at the end of these on tab added and on tag removed, I'm calli