Hi, everyone.
And thank you so much for coming today.
We're very excited to be here.
We're going to be talking about component architecture at scale.
But just before we start, Sherry, give us a quick introduction youth yourself.
SHERRY: Sure.
Hi, I'm Sherry.
Yeah, we are super excited to be here today.
A little bit about myself.
I'm working at frontend developer in Copenhagen.
I'm a woman technical lead.
And I have a lot of passion for the community and I have a way to make myself involved in
a lot of community projects.
We are going to mention only two of them here.
One is that proud organizer of ngVikings.
It's collaboration between the Angular meetup organizers in the Nordic, minus Iceland.
We have Magnus here.
And I'm a proud organizer of as well.
ANA: I'm Ana, I'm a developer advocate for Angular.
And I get very involved in the community.
Sherry mentioned ngVikings, that's me, and ngSpain is happening in June next year.
So, stay tuned because that is happening.
And also, if you want stickers for ngSpain, ngVikings or Angular, see us later.
We will be happy to give them away.
You're wondering why are we giving talks together?
We don't live in the same country, we don't work in the same company.
What's going on there.
Sherry, why don't you tell a little bit about us.
SHERRY: Sure.
I totally remember the day that we met.
It was a sunny day.
Definitely not in Copenhagen.
But in Spain at the Angular camp.
As they mentioned.
That we found out that we have a lot in common even though we live far and stayed connected.
And everything happened in Helsinki, and she couldn't be here because of a new baby.
And we ended up giving the introduction to Angular instead of her.
And while working on that, we found out actually we can work really well together.
Now everything has started there.
So, that was our story.
But Ana, I think you have a big announcement to make.
ANA: Yeah.
We do.
We are now the proud owners of Jurassic Park.
We are really excited about this.
However, there was a problem.
It was too zoo concept like for us.
And we really didn't like this, did we?
SHERRY: No, we didn't.
So, we came up with the idea to adopt all of these dinosaurs and take care of them.
But later we realized that we seriously have no clue how to take care of dinosaurs and
we didn't want to be an irresponsible parent.
So, we decided to actually build an application and put the dinosaurs for adoption instead.
It was a brilliant idea and we should start creating that here.
ANA: Remember that they have the applications and dates that we need already.
Why not use that?
SHERRY: That's a good point.
I don't want to reinvent the wheel.
But we don't know how the application is working, and if we go and use this application, they
have to maintain it.
Should we start by looking at the code first?
ANA: Yeah.
That's a brilliant idea.
Let's go have a look.
SHERRY: Yeah, let's go.
ANA: Okay.
That was really bad.
SHERRY: No, no, no.
ANA: Yeah, that architecture was no way SHERRY: No, no.
ANA: But Sherry, why don't you tell us what is a bad architecture?
SHERRY: I can clearly explain it by what we saw there.
What we saw there, it was basically a spectacle mashed together and then we even wanted to
add a few features.
It was totally not possible.
So, it was not scalable as all.
And maintainable, you really could not find out what it's worth.
Everything was basically one form.
It was not a good idea.
And reliable?
I'm not even sure how that application is working.
And definitely not for Ana.
As I mentioned before, start from scratch and put all of those dinosaurs there for adoption.
ANA: I agree that you can start from scratch, but you want to put all of the dinosaurs up
for adoption?
SHERRY: Yeah, what's the problem?
ANA: You are there are T Rexes and carnivorous ones that can eat us?
SHERRY: Are you Serious?
They can eat us?
ANA: I have taken care of them and it's good.
SHERRY: How?
ANA: I love dinosaurs, or I wouldn't have them.
I spoke to the herbivorous ones, those prosecute plant eaters, and they were excited about
having this application.
They already built it.
It's done.
SHERRY: In the last few minutes, they built an application.
ANA: Yes.
Go show them.
SHERRY: Actually, it looks good.
ANA: They did it, it is all done.
SHERRY: That's great.
But still, do you guarantee that they are not the same dinosaur that built the application
before?
I mean, sounds fishy.
A few minutes?
ANA: Yeah.
I think you have a point.
We should definitely check to see if it is scalable, maintainable, reliable and reusable.
But just before we dive into it, how about we tell the audience what we are going to
be learning today.
SHERRY: What we are going to do is how to split an application into a smaller section,
which are components.
ANA: Then we're going to see what the components are.
SHERRY: And then an overview of how ngContent can help you.
ANA: And we are going to see how components interact with one another.
Check out the components.
SHERRY: Yes.
I guess they are somewhere in the forest.
We have to go with our car there.
ANA: Yes, go find the components.
SHERRY: Okay.
This is let's look at the code.
Oh, no.
Can you see what I see?
ANA: Yeah.
Let's take a closer look.
SHERRY: Yeah.
ANA: What we have is a direct HTTP call from our component.
SHERRY: That's not good.
ANA: We don't approve.
SHERRY: We don't approve it at all.
No, no, no.
Why?
ANA: We don't approve because we had way too much logic for that component to hold.
We need to separate it and break it down more.
When we're talking about separating, we need to talk about the separation of concerns.
And here we have a direct HTTP call from a component and that shouldn't be happening.
Also, we need to make sure that component takes care of its own logic.
So, it has single responsibility.
And, yeah.
Now that we know why this isn't a good example, can you show us how we can actually save this
component?
SHERRY: Sure.
We actually can use services.
And what you need to do is that you need to extract what you saw that, for example, that
all logic related to how to communicate with the backend extracted from the component and
then put it in a service.
And then later on you can inject that service in any component that you want to and then
try it.
And then call it there.
So, in this way you can even inject it in many more components.
Write it once and reuse it later.
So, let's see how we created that.
So, we basically created a service and then we extracted those logic here and then we
created a method called getDinosaurs.
And then inside our component this time we first imported it and then we injected it
into our constructer and then we just called it and then used it.
So, oh.
>> Rawr!
ANA: What was that?
SHERRY: Ana?
ANA: I know it.
SHERRY: I do.
You know I said I took care of the T Rexes?
ANA: Yeah.
SHERRY: They're angry, I opened the cage and they just ran away.
ANA: You said they are SHERRY: Run.
Yeah.
ANA: To the next page.
This looks good.
SHERRY: This is a detail page.
But let's check the code.
Okay.
So, this is just like the first application we saw.
So, we have everything in one place.
We don't have any sort of well, they did make one component, right?
ANA: Yeah, they just heard that they should use components.
So, they just put everything here.
I cannot imagine that how oh, my god.
So SHERRY: It doesn't even fit on the screen.
ANA: No, not at all.
Really bad.
That is.
SHERRY: We definitely ANA: We definitely do not approve it, no,
no, no.
SHERRY: Okay.
So, why can't we approve it?
ANA: It's the concept, you put too much of the concept in one place and then you have
the separation of content and the responsibilities.
So, that's not good.
How can we save it?
How can we approve it?
As you know, Angular allows us to use component based architecture.
And component based architecture allows us to divide it into smaller widgets, components.
Before you start coding, get the mockup and start drawing rectangles around it which you
will divide as components.
And you can start deciding what's going to be a parent component, a child component and
that way you can start structuring your application.
We already did that.
This is what we did and our way of structuring it is not always the best way because it depends
on the application.
But it's a good start.
SHERRY: Yeah, it's a good start.
We can look at one of the components that we created which is the product.
So, in this part while you're adopting a dinosaur you can also go ahead and then buy some product
that dinosaurs like.
And so, let's see how we did that.
So, what we created, it was a specific product component.
And then we passed.
These are the data that they received.
One is about the list of products, and then the other one is about the dinosaur's habit.
The product that they like, or they don't like.
And then because they can buy it, so, they need to have kind of a way to communicate
outside of that component.
So, we have an app by.
So, look here.
We only put all the logic that we need inside this component here and then we ignore the
rest.
I mean, because the rest they are in the different components.
So, everything is nice and clean.
And then that component, actually the treatment is pretty simple here.
In this way, if tomorrow there is a problem with the product, we know which to open.
You don't need to control shift F to find the thing that you want.
So, you open the file that you need.
So, I would stay that we are good.
ANA: Yeah, but Sherry, lately I have been hearing about the components, can you explain
in SHERRY: I can do that.
We can categorize our components into two types.
Stateful components, or smart ones, or stateless component or the DOM one.
Stateful components are the one that they care about the kind of the business logic.
So, everything in all the business logic that we have there, they are normally tied to a
specific user's story.
And they also are the one that they care about how to communicate with the backend, for example,
and get the data.
So, these are not normally the type of component that they are the best candidate to be reusable.
And a stateless one, they are the one that they literally don't care.
But they just get the data from wherever, normally from the parent.
And then they just display in the way that they want to.
So, these are the best components.
This candidate to be the reusable one.
Okay.
In our story, what we need, we make one stateful component.
And this is the one that we also injected the service there.
So, that we got the data that we want, and the rest of our component in this way they
are stateless.
But today we can pass the date off for the dinosaurs.
Tomorrow we can pass the date off.
Yeah.
So, yeah, I guess we were good.
ANA: Yeah.
Let's run off to the next component.
SHERRY: Let's go.
ANA: Check it out.
SHERRY: Okay.
That looks pretty.
ANA: Let's look at the code.
SHERRY: No way.
ANA: So, there's basically a copy and paste with just the change of header.
So, this would be like do you know what this would be like?
It would be like having two Sherries.
SHERRY: Okay.
ANA: But with a different name.
SHERRY: Another me?
ANA: We don't need two Sherries.
SHERRY: One is enough.
ANA: So, we do not approve?
SHERRY: One is enough.
ANA: Why don't we approve?
SHERRY: The dinosaurs thought they were too smart.
They had similarity into two forms and copied and pasted and changed something there.
In this way you're basically repeating yourself and you really don't want to repeat yourself.
I noticed on the component there was a kind of a type of food.
And if you want to add a couple of things more to that, that section, you have to do
it in two places.
So, you have to maintain this in two places as well.
And as the product grows, so this can easily get out of hand.
So, this is not good.
And testing is something, but two times and it's not too smart.
And as I mentioned, it's also not maintainable.
So, Ana, how we can improve?
ANA: In this scenario, we can use ngContent.
In AngularJS we had transclusion and then slots.
This is the same thing.
It acts as a place holder in the code which you can then reuse later.
What we did with these forms is we put one form, we didn't have two forms, we have one
form with the same content and the places where we needed the change, which were two
places.
One was the header and one was the button.
We added the ngContent tags.
And what we do here is we add a select attribute because we have more than one piece or element
that will change its data.
And when you add the selectAttribute, you have to tell it which element you're focusing
on.
In this case, the h3 and later on.
And how do we pass data or whatever we need to this ngContent tag?
What we do is add our component.
In our case, we did it in the add component file and add the element that we need to change.
And the h3 and the button and then we just pass whatever we need through there.
This is a pretty simple example, but it can get more complex.
You can add another component inside or whatever you may need.
So, I think that component's done with.
SHERRY: Yeah, it's totally good.
Up to here we found out that how obviously that application into a component and then
how we make it flexible while using ngContent.
But Ana, how can these components talk and communicate with each other?
ANA: Well, the best practice is data flow.
Normally we would have a stateful component which passes its data down to its children
components or stateless components.
And if there was an event to occur, that event would then be passed up to the stateful component
and then be handled.
Let's take a look at the example.
Now, say that the right hand child component decides to have a change.
An event change, for example, a button click or some input or whatever.
That would then be passed on to the parent component which would then be passed on to
the stateful component which could handle that event and pass back down the data that
was necessary.
This is really good for debugs.
Because you know exactly what's going on.
But imagine if you had an example like this.
Like we're gonna have the same thing happen.
So, we have an event happen.
And all of these things change.
I don't know about you, but I would hate to debug this.
And I wouldn't even want to look at the code.
So, we just want to have a friendly reminder that events up and data down.
Okay.
So, this is a very simple scenario that I showed you.
But imagine if things got more complex.
Sherry, what could we do there?
SHERRY: Yeah.
I can explain it with what happened to us.
This dinosaur came to us and ask for a new product which is pension product.
They said what happened to us when we get old?
I said that, okay, we can fix it.
And we started to build some pension product with it.
But then soon realized that each dinosaurs get adopted in different countries.
And these countries, each of them, they have their own pension rule.
And then we started to build components, components, and then realized that to implement all of
this logic we had a toggle in some part of the form and changing some of the form because
of the business logic behind it.
So, we ended up in a nested, nested, nested war.
We said that, okay.
We can handle it because we know that as soon as we stick to the flow, which is input on
and event off, we can eventually go ahead.
This is a good practice.
It's okay.
But we realized that actually our application was so slow because of those nested nested
components, that they want to talk to each other.
And by having all of these meta layers, especially those toggles that has changed something over
there.
It was slow.
We thought it was going to be easy to debug.
But no way.
In that nested world, we could not fix it.
So, what I talk basically was, for example, in the component tree that you have a toggle
in A and that is going to change the one in B.
And we could not handle it.
So, do you have any solutions for that?
Because I know you have all the answers.
ANA: I wish.
Okay.
So, it really depend on the scenario and the application.
But a good starting point would be going back to ngContent.
Now, before we describe how it can make a component flexible, but it can also help when
it comes to flattening the component tree.
So, say we take our example from before where we had those two forms instead of one.
What we could do is just make the one form instead of having two and we would actually
have one layer less on the component tree.
And this would increase performance because we wouldn't be having so much change detection
going on and so much inputs and outputs.
So, that is one approach.
What would be another approach, Sherry?
SHERRY: The other approach is that we use behavior subject.
What is unique about them is that they are observers, that they can be observed.
And also, the cool thing about them that no matter that when you subscribe to it, it's
going to give you the current state.
So, even if you subscribe it late, you still will get the current state.
So, what we decided to add to our application was that happiness indicator.
So, as more product that the dinosaur lucks that the happiness increased or decreased.
So, you can say that the product component is going to be totally tied to the other component
up there.
So, what we did, we created a service and we put that behavior subject there.
And then the component A and B, they're both being injected in there.
And then as soon as so, in this way they both post directly to this service.
And most of them can get the current state.
So, even if for another feature that the dinosaurs may ask us.
So, we going to add a new component.
That component can also get the current state.
So, you can have as many as whatever subject as you want in your component, in your application.
And it's going to help you.
And it's a good practice.
No worry about it.
But later we realized that for that pension one, it was not enough.
ANA: No.
It wasn't.
The other approach we have is actually state management.
And this way we can hold all of the state in one place, unlike the subject where we
have to stay in several places within the application.
So, what I mean by this is that we will have the service that will pass the data on to
our store which will handle the state and then pass it down to the stateful components
and the child components.
And, again, say the right hand child has an event that could pass it up to its parent
component which would then pass it on to the service which would handle this event and
pass it back to the store.
And that store would handle it so that with the help of selectors we can actually send
down the data that we need to only to the components that we need to.
This is a really cool thing about state management.
But the thing is, it's become really trendy and everyone seems to be using it even when
they don't need to.
So, we really want to emphasize on the fact that you should only use state management
if it's necessary.
And if you want to know when you can use it, there's actually a really good talk after
lunch by Mike Ryan.
You might not need NGRx.
SHERRY: Yeah.
I personally want to invite you there.
He's talking about Sherry principles.
It's spelled differently but pronounced the same.
Come to his talk.
Up to here, we found if you use ngContent you may be able to remove unnecessary layers.
With behavior and subject, you can have the method partnering.
And if you want to keep the states all in one place, you can use state management.
ANA: Okay.
I think we're done here.
SHERRY: Yeah.
We're done.
ANA: But Sherry, with a does the future hold for us?
SHERRY: Yeah.
Well, there is one thing that we created all of these components and made them come together
with each other.
But we can go a step farther and use web components which is our favorite topic.
We can talk about it forever.
But we don't.
We can do it with Web Components.
They are using browsers capability.
I pronounce it wrong.
Okay.
So, because of that, we can actually if we can write fewer lines of code.
But the we can gain the formats because we are using what that web browser is doing.
So, we can, for example, take advantage of change detection in the browser.
So, it will bring us a lot of features including being platform agnostic, so you can actually
share your components in the open source world.
And no matter who is using what what framework, they can use it.
And even if you want to have a migration plan to some other frameworks or even from AngularJS
to Angular, you can also help it.
And now with Angular Element, we can also use it.
So, go ahead and read about it or you can come later and talk to us.
We can talk.
So, is it the time to talk about the ugly part?
ANA: Yeah.
So, even though we tried to make our code perfect and our architecture spot on, there's
always gonna be 20% of that code that we hate and that is really horrible and that's okay.
It happens to all of us.
But make sure that the 80% is spot on and you're good to go.
There isn't a one solution fits all when it comes to architecture.
It really depends on what application you're building and also if it's like form driven
or data driven it will really depend.
But we want to say is that even if you think that your application isn't going to scale,
always prepare it for it to be scaled from day one.
Because it probably will scale.
And if it doesn't, at least you have a neat and tidy codebase.
And a piece of advice: We want to say we've insisted that you need to break down components,
but make sure you don't break them down too small.
There are limits.
Not too big, not too small.
Medium.
Also, keep them simple and stupid.
Do not overengineer your application.
It's not necessary.
It just makes it too complex.
And also make sure that your components are testable.
Now, as we're finishing, we would just like to say a massive thank you toed, Mike, Brett,
Quinton and again Mike.
The other Mike.
Because without them this talk wouldn't have happened and we're very grateful for all of
their help.
And also, a big thanks for Sherry's dog who appears in that for all the mental support
he gave us during the shooting.
ANA: And thanks for being here.
I know you're hungry, you want to run to the lunch.
But before that, we have something.
We promised to say who is our favorite dinosaur.
And it's actually Laski who has a badge thanks to AngularConnect.
You can follow us on Twitter and we are going to share the slide.
And you can come and talk to us and, yeah, see you there.
Thank you.
[ Applause ]
Không có nhận xét nào:
Đăng nhận xét