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.