Angular Elements – Rob Wormald – AngularConnect 2017

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
ROB: Thanks, Naomi. This is something I've been waiting to talk about for 18 months and talk to the Angular team, so I'm pretty excited to talk to you about it today. I'm Rob Wormald, a developer advocate, work on NgRX. Follow me on Twitter. We are going to be talking about is under the Angular Labs umbrella. This project, we are reasonably happy with the way things that are going and reasonably happy with where the APIs are, so things could change, so a little bit of a warning here. Let's start - I think that Angular at this point is ideal for building ideal applications. Everything we build, our tooling, documentation and infrastructure, we are building it for this use case. But, it can be a little bit more challenging to use it in things that don't fit that single-page application model, right? Things like enhancing existing HTML pages. In AngularJS, you could take a page, put Angular on it and sprinkle some Angular in there and boot up and magical features would be added. We got asked a lot. Being part of a developer-advocate is being out in the world talking to teams that are building with Angular, and we hear this request a lot. This is challenging because Angular owns the entire DOM inside of a component, right? So it's hard to interweave and mix and match. Content management systems come up all the time. They are driven by a database and you've got non-developers logging in and building components and things like that. These things are server-rendered, right? You want to make sure that it's fast when you're talking about content. I like to call these layout or attribute-driven. You want to configure them, set the attributes, and set content to them. You don't necessarily want to do this as a single-page app. Then widgets. This is a kind of a catch-all term for all sorts of different cases. Widgets are things that you embed in other places. You might want to unit a unit of functionality and put another application or put it on a site. Maybe put it on a site that you don't only. You're a company and you have a service, or you have some product that you are selling and you want to be able to give other developers widgets to embed in their pages. Mixed environments. When AngularJS came out, it was the bees' knees, the only game in town. Several years later, there's a bunch of great frameworks out there. We spoke to lots of companies who might be using one, two, or all of these technologies. Angular is interesting. None of in these things talk to each other very well. You end up doing a lot of bridging and glue code. It is not super nice. Then I've got to say sorry to Ward and Jesus. They talked about how they did Angular.io. I sort of deprecated their talk yesterday. So, if you look at Angular.io, our website is mostly content and static HTML. If you've got static HTML, you don't want to turn it into an Angular component because you're generating a lot of unnecessary code for stack HTML but you want to embed these widgets again with the functionality into these static pages. So, you can actually check the code out for how this works on the Angular repo rate now, but it is pretty complicated. You look and like we've built this live example, it is really simple, and this is how you think it works, but it actually works like this, right? You get a bunch of code, doing things like factories, wiring them up manually. These are notes for ourselves going what are we doing here? There is a hack note, preserve these things. This is non-challenging and code written by us, right? This is non-trivial. More code to make this working with right? You're dealing with change detection manually. You're dealing with each time things get destroyed, you have to clean them up. It is possible but it is not easy before and we have this thing at Google too, right. At Google, we have different frameworks, Angular, and teams using AngularJS, Angular Dart, whiz, Polymer. There are a ton of other frameworks, and we want these things to work together. Internal teams want to share code across teams, use things like web-workers and the cool things that Angular does, and teams migrate, change, move apart, so people are trying to rebuild the world every time they do anything. For me, Angular Components can be tough to use outside of templates or even more tough to use outside of an Angular application, right? The last thing I want to point out is reusable components. I'm a web developer. I've been a web developer for a long time. And I in my career have problem written a does date-pickers in various flavours. You can see on MPM there are 872 date-takers that people have implemented. I think it is a shame that we keep redoing the work again and again and again. It's a little bit of a shame that we have all of these people in this room, all of these people in the Angular community building these awesome components, these awesome UI libraries but most only work inside of Angular application, right? I know they share across different teams and platforms but doing a lot of work to glue these things together, so it's kind of a shame. We started this by asking, can we do better on this? Can we make this easier for Angular developers? And maybe kind of close to my heart, can we maybe make the web better for everyone, not just Angular developers but anybody who works on the web, right? Can we make it better? So, we will take a little bit of a detour here, but let's talk about web components for a second. Raise your hand if you've heard much web components. If you're watching on the live stream at home, that's pretty much everybody at home. Raise your hand if you've used a web component. If you're watching on the live stream at at home, that is less. Maybe 12 if you've written one. Web components are a set of four specifications. They've been around for a few years, designed to make web applications to build. Part of this is HTML templates. This is stamping out DOM. You know this in Angular today it NgTemplate. Create a unit of UI you're going to stamp out repeatedly. Shadow DOM, their styles don't leak over the page. We use this in Angular today. We know this is shadow DOM. HTML imports are a proposed spec. They've been deprecated, not going to go anywhere. This last one is the one I really want to talk about. So custom elements are with what makes web components. Custom elements allow you to create HTML tags and just drop them on to pages, right? It allows you to mint elements that work exactly like native DOM elements. There are standard ways to define a web component. Version one shipped in chrome and safari so this covers something like 80 per cent of the web and then Firefox and Edge, they have in in development and you can polyfill back to nine and ten. So creating a custom element, you put on the page, it boots up, it works, it's a really, really nice experience. How do you build these things? You've heard much class, just extends from HTML be, and then use window of custom, and then you put it in the page and it boots up and starts working. Custom elements allow you to observe attributes. You can say, "I want to listen to this attribute on the element changing, give me a callback when it changes." If you're paying attention, this looks a lot like Angular changes. This is a life cycle hook - when something changes, tell me about it. In the DOM, you can set that in the DOM. When you change that value, it will trigger that callback, right? You can do this programmatically. Under the hood, this is what Angular is doing with something like that, you get hold of an element, you can set attributes on it. The same thing works for properties, right. So you have setters and getters, and say when somebody sets the current date property, update the DOM somehow, do something, right? Get the current date. So again, this is analogous to the input, a property of that component. You can do this programmatically, get hold of the element, do picker and have the date. You can do events. You can dispatch events from a custom element when something happens, when someone clicks a button or changes a date in the date-picker, or whatever, dispatch an event to the outside world. You can listen to it. The key thing I want to point out is these are completely standard. Everybody who is a web developer knows how these things work because this is how the entire web works. Have they have life cycle hooks. They are connected, when the element is connected to the DOM, fire this callback, and when disconnected, fire this callback. When the attribute changes, we have this callback and the adopted callback which allows us to know basically when an element has been moved from one document to the other. I've never actually found a use case for this, but it is in there. Interestingly, custom elements web components work in Angular. This was a design goal from day one of Angular that you can go ahead and take any custom element, drop it into your Angular template, and it will just work because Angular sees it as a DOM element because it is a DOM element. You don't have to do anything special or think about this in any special way at all. Also, interestingly, it is actually impossible to tell looking at this template, is that an Angular component or is that a web component? There is no way to know. It is exactly the same syntax. This is important. This is great. Let's do everything this way. Everything as custom elements. Some people think this, right? Web components.org is run by Google with keeps track of the different components available. You can see our friends agGrid down there. This is what I was talking about, they have to manage a special flavour of their grid. Our friends at Ionic have been working on stencil. They want to grow larger than just the Angular community. They built this amazing set of tools and components and they want other people other than Angular developers to be able to use this. They've started under the hood in stencil creating web components. All that stuff is going to feed right back into Angular. Angular supports web components already out of the box, stencil components will roll into Angular apps with no problems. So why isn't everything doing this? Why don't we just do everything as web components? This is kind of the problem here, right? This is a very simple check box. You can check it out in Google chrome, the how-to components here. This is a best-practices example of how would you build a custom check box, right? You can see there are a lot of manual DOM manipulation here, checking attributes and checking, if we have attributes, we're doing a thing, and, if not, dealing with properties being upgraded, adding event listeners here. It keeps going. When the attribute changes, if this happens, we do this, and it if this didn't happen, we do this, right? If it is going, right, we set, check the values. All this stuff is why we use angular. Nobody wants to do this or write this kind of code. It is buggy and hard to maintain. Your job is to make things work. Your job is not to deal with attributes. Nobody wants to do this. Of course, you know, we use Angular because it provides this amazing platform of stuff, right? You get all these amazing things - internationalisation, you get CLI, animations, mobile tool, DI, upgrade - all these amazing things that Angular gives you. Web components don't give you any of these things. It is a lower-level primitive. We're talking about low-level APIs, not components, not things you're using to solve business problems. So what did we didn't have to choose? What if these things weren't mutually exclusive? What if we could get the best of both worlds, all the great things about web components, they just work in the browser, they work everywhere, everyone knows how to use them, everyone knows how to consume them? That's what I'm here to talk about. Angular Elements is a project we started, and Angular Elements, we want too take Angular components you're writing today, every day, and package them up as custom elements so they work everywhere. Simple. In Angular, it wraps an Angular component. We have a wrapper, a custom element. It bridges between kind of these DOM APIs I was showing you and the Angular component, your business logic. They're self-bootstrapping meaning you put it on the page and it starts up. You don't have to query for it or manually correct it. You don't have to do the stuff that Ward and Jesus were talking about - it just works. This word "host", I want to point out, if you're an Angular developer today, you're probably already using the host extraction. You know about host listeners and host bindings, right. What you're talking to, what that word "host" means is the real DOM element that your component is connected to, so, when you want to keep these attributes and properties in sync, that's how it works. We take your components at input, your component 's public API and we bridge it. We say when you set the property on the custom element, we will go ahead and sync it into your input and trigger change detection. We will go ahead and get that go and make it dispatch these custom events. From the outside, you can consume it as an add-event listener thing. Things like listeners and bindings, we can do all of these things. They are very, very close, the life cycle callbacks the custom elements have are close to the life cycle callbacks that Angular has which is on purpose, not a fluke. Zones are optional. Zones are great when you have a big application, you don't have to worry about change direction, it makes things nice and easy. If you're going to put this component in another context, a different page, put it somewhere where you don't control the application, zones, challenging. They integrate with the whole application. So, in version 5 of Angular, we made zones optional. You can turn them off. Take control yourself. And so with a custom element, we basically turn off zones and we just link change detection into your setting and setting those properties and listening to those events. We make it magical and link it up for. It's an Angular component on the inside with standards on the outside, web standards on the outside. This means again that anyone who can consumes this component, anyone who uses it, pretty much knows how it works already. They don't have to know anything about Angular to use this component. So let's look at an example. This is a progress bar, this is a vanilla custom element. You can see there it's a progress bar that extends from the HTML element. One thing I want to point out about that is that makes server-side rendering challenging. If you're doing server-side rendering, there's no HTML element because there's no DOM. Doing a native element this way or a custom element this way is fairly restrictive. Again, we're doing manual manipulation here. When we set the progress, we will keep the attribute in sink, also keep the RE value in sync so we get accessibility from this, putting in the manual shenanigans. This is the exact same component written as an Angular component, right. We're using the host binding saying when the progress value changes, keep it in sync with the attribute. You know, the area value for the progress. Again, when you set the input, we are going to expose that to the outside world, and we run it through Angular's compiler. If you look at these two things, they're not all that different. The templates look reasonably, the same, expressing the same sets of things, but the one coming from Angular will server-side render. We can do what we want with it. It is very flexible. We want to do everything that a web element does inside element with far less code, shenanigans, I have no logic at all in this code. It's zero input, keep it in sync with the value on the screen and the data binding takes over. I have a couple of demos to show you here. So this is that progress bar. This is that progress bar we were looking at, right. A very simple thing. I want to show you how this works. I'm going to go to my console here. This is a simple page. I will show you the elements page here. If you look at the body. So, inside of the application, we have basically my NgProgress bar. There is a shadow root here, and you can see the value changing, so actually keeping the attribute in in sync which means the accessibility works out the box. What is important I'm doing a document query selector, getting hold of the progress bar, doing a set interval. There's no Angular here again. This is extremely standard boring JavaScript. We are setting properties, setting attributes, right? This is where it gets cool, though. So I can go into my console. I can say let's my my const progress bar is document.preselector. NgProgress bar. That's my fault. Apologies ... . So, my part is where I have the other one stored in my script. How, I have a hold of this element, my progress bar, I can do stuff with it. I can say my progress bar. It just works. More interestingly, though, you saw what Ward and Jesus did yesterday, all that manual work you have to do to create one of these components, connect it to the DOM, what if I wanted to create a new progress bar, create a new version of these? Very simple. What I want to do is get a hold of the constructor. I had call this Progress bar. Bit into the browser here is that custom elements API. I'm going to say custom elements.get. Mying the progress bar. I don't need to go query for that. Come on ... . I get basically I've said to the registry, give me the constructor for this custom element, and now I can just do this. I can say let a progress bar is equal to a new progress bar, right? So now a progress bar is - and it works. And so this means that, for many contexts at any time, you've give anybody an Angular component, they can put it in any page they want, and it just works. This is programmatic, simple creation developments. Cool, right? Now, let's look at another one. So, this is a very simple tag. This is a simple "hello, world" component, I'm going to go into the DOM and poke around with this one. One of the things you may not have ever tried this, but if this was an Angular app, not an Angular element, if you went to change any of the properties in the DOM, nothing changes because Angular is not actually listening to the outside world. It's very much a one-way thing where Angular reflects the content out, right? But of course, if you're doing this from a CMS or if you're doing this from some other context, you want Angular to be aware of when you change an attribute other a property to keep thee things in sync, right? So I can actually go into the DOM, into the inspector here, and say, "Hello, Angular", and it just works. Again, we are opening up this API that allows it to work. It is a completely standard DOM element. We're closing a loop where it is so close today to making Angular components look like web components but they're in this uncanny value where you expect it to work like a web component but it doesn't. All elements does it close that loop and make it consistent and glue together properly. Now, of course, the Angular team manages the Angular material project, right? We've got dozens of amazing components, so again, it would be super cool if you can use them in any application. This is a demo where we've taken Angular material, checking the console here, and we've said let's turn these things into custom elements, right? We do it with custom elements. Now going into the inspector. The font size. Good call. Thanks, Igor! Cool. So I can go in here. Now you can see I've got a map progress spinner. This is a material component, made it as a custom element. This works in any context. I can get in my inspector here into the console, clear that. It's my progress bar, right? Cool, and I can say the value is 50 or the value is 30, or the value is 99. So what we are doing here is making the Angular material library again available for everyone. Any application can use this. What is cool about this is if you're building an Angular application but it is going to host on a larger site, maybe host somewhere in your organisation's application, they can use the same Angular material components. You don't have to go and recreate the world to make the rest of your application look like your Angular app, right? And so one of the things that comes up a lot is we want to be able to play - and I mentioned this earlier - between different frameworks. One of the things that I talk to a lot of different companies about is they're using as I said a couple of different frameworks. Netflix uses six frameworks when they build applications. It sucks that they have to rebuild the world. I've been talking to Jason Miller who runs the Preact project. I wanted to to make sure that it makes sense that Angular and polymer work together because they are similar, but Sgt like Preact or React, it is different to Angular, it works in a different way, uses Jsx, not templates. I wanted to validate this is the right thing we can do, the final countdown challenge, if we can make this work, we can make anything work, right? This is kind of insane. But we've got a demo Preact component here, using JST of all things to render an NgProgressbar. Again, Preact doesn't care it is an Angular component, it is just a web element, right? It's a DOM element. It means every framework that talks to the DOM automatically works with this stuff, right? So, this is the project early on. Where do we go from here? We want to make sure we can validate the right thing for you with be talk about best practices, on the web team at Google to make sure we are doing the right thing here. We want to upgrade Angular to use the shadow DOM, make things more ergonomic, and make sure there's a lot more use cases here that this is going to cover. If this is something that interests you, please drop us an email. Come and talk to me today or tomorrow. I will be around. I love talking about this stuff. It's all I've been talking about for the last 24 hours. I will keep talking, and talking, and talking about this. Before I go, learn more. Again, you can check out, this is merges to a branch on the repo. We want to make sure that it is ready to go before we put it out to the world. You can pull out the branch and play with it. Also check out these two articles from the Developer.Google site. Special thanks to George who implemented the first version of this with me. Great work. Rob Dodson from Google who has been a great help in making sure that we do the right thing, that we are getting the right elements play nicely. Adam Bradley and Ionic stencil teams, and they've been a great help. Adam and I have been talking about this for a long time. I'm super excited to see they're doing it and we're doing it. The polymer team, they've been talking to us about what we are building plays together nicely. Angular Elements - we will let you know when it is ready to go. We think it is going to be a powerful API for Angular and super useful for all of you. Thanks for listening! [Applause]. NAOMI: Thank you so much, Rob. Folks, there is lots going on after the break. Stay in here for Angular Forms with Kara Erickson. Over in Saturn, four-day data binding, in Venus, we will have the mini workshop. You do not have to register for this, it is free. This is the same thing that was demoed last night. Over in Pluto, our migration panel. There's a fantastic Barista cart from rangle.io. We will see you back here at 11.20.
Info
Channel: AngularConnect
Views: 8,291
Rating: 4.8928571 out of 5
Keywords: angularconnect, angular
Id: vHI5C-9vH-E
Channel Id: undefined
Length: 27min 32sec (1652 seconds)
Published: Mon Dec 11 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.