Nir Kaufman - Angular DOM Manipulation Techniques in Dept | JS VidCon

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi everyone i'm very happy to be part of this uh online conference this is my first online conference and i think the first time that i'm delivering a talk you know in a conference in front of a camera and not in front of real people so let's hope for the best i'll do my best and hopefully we can all learn something from it uh let's get started we don't have too much time and i've got a lot of things to share with you so let me start by introducing myself real quickly my name is nir kaufman i'm a principal consultant at 500 tech based in new york i'm a google developer expert in angler i love the community i run meetups i contribute to meetups this is my alter ego right there uh he's my special guest in my react nyc meetup uh if you want to learn more about me or find reference to code slides and basically everything you can check out my website near that live or follow me on twitter and today i'm going to talk with you about uh daw manipulation in angular so let's keep it practical which means that uh dive in into implementation details that's great i highly encourage everyone to investigate to learn how angular works under the hood i think it's a good knowledge but you know one of the most common things that we do in our angular project or day jobs is not digging into the source code is more like build components build ui move forward so what i would like to do in this talk is to give you some knowledge to to to go deep on a topic but to end up with the practical usage of this information hope you gotta succeed with it um well the first thing you need to know when you approach dough manipulation in angular is that there is no dough well yeah all of us knows i mean most of us knows that angular provide us a thick obstruction on top of the dome but angular can run on different environments so it's important to use the correct language so let's not call it a doe manipulation let's call it view manipulation let me explain when we create a component in angular basically what we're doing is providing instructions for the framework so angular can create an object called view and this view in case of a component represent is an internal data structure that represents well a piece of view a display element that was created if we talking about components from the combination of a javascript class and a template string that represent um you know the html the dom it's going to end up as dom there are two types of views and this is one of the most common questions that i hear there are embedded views and host view so this view object can be created out of components but on the other hand we can instantiate a template and then we can get a view which we called an embedded view which is not created from a component and we've got great use cases for both of them not every time when we want to reuse a piece of ui we need to create a component sometimes it's a complete overhead so what is this view this view object that angular creates for us well it's an object and it's hold references to dom elements if we're running on top of the browser it will reference to other host views which means it can contain other components and it holds references to other embedded views so basically by the end of this process we're going to get a tree the view hierarchy in some way it's a little bit similar to the concept of a virtual dom but there is a difference because this hierarchy is higher hierarchy of view object is not necessarily related to the hierarchy of the dom element that going to be created out of it which means that we can get a one view hierarchy a specific order of view object but the dom elements gonna look completely different the hierarchy gonna be different it's a little bit confusing but hopefully when we get to the to the example it all makes sense so in angular we don't manipulate the dom we manipulate views and when we're talking about manipulation just before we jump into the demo um it's important to to understand that there are basically two types of manipulation uh there is structure manipulation so we can you know manipulate the element structures um and for this we've got a dedicated api and there is a property modification which means we're not gonna change the order we're not gonna change the structure but we are going to modify some properties for each one of those manipulation angular providers and api and it's important to get familiar with this api because we're going to see soon what's going to happen if you don't use the correct api to perform uh some kind of manipulation so in angular if i want to manipulate the structure of elements i'm going to use the view container class and that's the only class that i'm going to use and if i want to modify properties i'm going to use the renderer 2 class and nothing else so it was a quick intro very high level so let's drop the slides and just jump into some code and you know start to see those concepts in real code so i've got here a brand new kind of brand new angular project i've got bootstrap bootstrap the css framework so i can use classes like container and let's just see that just you know make sure that everything works angular playground let's jump to the browser and we've got an angular playground which means that yep everything seems to be up and running first thing i want to show you is try to expose this view object that angular created for this app component and it's not magically created it's created for this app component because this component was provided in maintes to the bootstrap to the angular bootstrap method we're going to use di we can use di and inject the viewref now because i'm inside a component when i'm injecting the view ref hopefully i'm going to reveal the underneath view object that was created for this component so i'm going to implement after viewing it like the name suggests it's a piece of code it's gonna run after my view is ready and then i'm gonna take this vref and i'm gonna log it to the console so we can see how it looks like if i go back here to the browser and extend this object this viewref you're going to see well i've got an object and this object holds a property called lvu which is an interesting structure and if we scroll down we're going to see that it's hold references to a div with a class container which and for the h1 element and the text element so this view hold references to some dom elements now let's see what's going to happen if we manipulate these dom elements but not using the correct api for this so i'm going to create an h2 i'm going to call it a subtitle i'm going to take a reference to it i'm also going to take a reference to this wrapping div and now i'm going to use view child which is a view query to get a reference to this container so i'm gonna get here an element ref ella meant ref and i'm gonna do the same thing for this subtitle let's call it well sub title look carefully this is the view child you see the name view and we're implementing after viewing it not not no after dom in it and we're not going to a query template child or a dom child everything is related to this view object now let's use a class that we shouldn't use in order to remove this h2 element from this hierarchy so i'm going to inject renderer and then i'm going to use this class or one of its method this renderer remove child i'm going to pass the container and i'm going to pass the subtitle and then i'm going to take this vref and log it again to the console all right so first of all if if we don't run this piece of code we're gonna come here we see the subtitle we're going to the elements we extend it the uproot we can find the div we can see the h2 right here on the dom if we do run this piece of code and come back here well we're not going to see it if we're going to explore the elements we're not going to see any h2 whatsoever but if we head to the console and explore the view object that was created under the hood and extend the l view right here and scroll down we can see that angular keep a reference to this h2 element although it was removed so here is a proof that well you can remove dom elements you can remove elements from your template it doesn't mean that you remove them completely angular is still aware of it because we haven't used the right api for this now it might not seem like a huge problem here but let's look at another scenario and then jump straight to the demo i'm going to create a component right now i'm going to call it uh the child and my child component is not going to do much we're going to keep this child work but i am going to implement do check because this piece of logic going to run every time change detection check this component so i'm gonna log here something like checking the child component and that's it right so the child just logs something when change detection touched him i'm gonna go back to the app component and instead of this h2 we don't need it anymore so i'm going to remove this i'm going to remove this piece of code right here all right and i'm going to use tp the child this tip is just a prefix data that i used in this project so if i go back here to my project we did something wrong here as i can see the child works so this component rendered and if we check the console we can see here checking the child component now that's cool that's what we expected i'm going to go back to my app and i'm going to create a button let's give it a nice class so btn btn primary and uh click this button is not going to do much i'm going to implement a method let's call this method nope because every time i'm gonna click this button i'm gonna trigger change detection so every time i click you can see the child components being checked which again make total sense it's a child of the app component cool now let's use let's take a reference to it so instead of subtitle i'm going to take a reference to the child component i'm going to tell angular that i don't want a reference to the component instance actually i want to read it as an element ref want to get a reference to the element and i'm going to write the same code that we wrote before this renderer remove child again this container native element and this um oh it's still a subtitle let's change it back to something like child component and let's remove this child component native element all right so if i go back to the to the console i don't see this child element if we check the element is not there you see the div and just h1 and the button but look at this if i click change detection still run on this component because i remove the element underneath angular still thinks it's there because i didn't use the correct api to do it cool so there is a correct api to manage views let's have a look on another type of view because we just see how component works let's create another type of view and then see how we can manage it correctly i'm going to create a template and ng template tag and here i'm gonna put some um piece of like an element that won't be rendered so you can't see me and if i want to be able to uh remove this element from the dumbbell in the correct way first i'm going to have to create a view container a place on the dome where i can use as an anchor to attach this template this view so i'll be able to manipulate it in a correct way let me just show you how it works so here i'm gonna create a container and here i've got this template i'm gonna query this container and i'm gonna tell angular a i don't need an element element ref here i want you to treat it as a view container reference and hey i don't have a child component here anymore i do have a template you don't need to read it as an element ref i do want to get a reference to this template he's shouting at me because this is a generic class all right and now i can use this container actually first let me create a view so i'll take this template and i'm going to create a view out of it so now here i've got a view ref and then i'm going to take this container and i'm going to insert this view into it so if we run this code right now in the browser you're gonna see the content of the template and if we extend this vref l view and we're gonna scroll down a little bit we're probably gonna find it here somewhere like here's the container and inside this container here is uh where are you where are you an embedded view maybe that's the wrong container all right here it is the embedded view right here you see this array of one embedded view and if we check the elements i can see the app root i can see the div i can see my container right here right here it is the container sorry and i can see this h2 sitting right beside of it so all right so so what's the point let's say i want to remove this template but now i'm going to use the correct api to do it so let's get our button back this time it's going to do something useful and now what i'm gonna do i'm going to use the correct api to remove this view i'm going to use this container clear and just for case i'm going to console.log the view again and you know what i even gonna create another view like view two and i'm gonna insert view two as well oh right here it is so if we go back here i can see two views that i attach i insert them into a view container and now i'm going to use the right api the view container api in order to remove them they've been removed from the dom but more importantly if i go to the console i refresh for a second this is the viewref before i remove this so if i scroll down i'll find my container i think it's right here as you can see here two embedded views array of two embedded views and then if i'm going to remove them and look for them on my vref of you you're going to see that well you can look for them but trust me you're not going to find them so it is important to use the correct api to remove elements well we can talk about this for hours trust me and actually if you speak hebrew there you can find on youtube i'll share the link later like eight hours of this uh digging into this topic but um it was a short talk we haven't finished yet i want to show you the final demo and hopefully you got like the idea or a good direction of you know how to manipulate structure what to look like and learn some new language and like i promise let's try to take this and actually look at the look at the more like practical usage of this knowledge so for this i'm gonna i'm gonna introduce you something that i implemented more than once in my career first i'm going to drop here some markup so what you see here actually what you see here let's go back to the browser what you see here it's like something that look like i don't know like almost every dashboard app out there we've got a few areas here i've got the header i've got a sidebar and i've got a footer if i go through the code you'll see that this is just markup right just a structure i've got a component that represents the sidebar components represent the nav bar a router outlet here where i render my pages each one of the pages is the component and a footer right here and if we look at the project you can find the pages this is the home component the profile component the project page and some layout component here is the footer here is the header and this is the sidebar all right there's nothing here which doing anything important right now what i'm gonna implement is something similar to the concept of a portal if you heard about it if you play with it before it's an interesting way to dynamically render some views but in different places of the in the tree which means like give us some freedom to render stuff all around without the hierarchy restriction what i want to implement is this every page the home page the profile page the project page each page within its own context gonna going to be able to render stuff on the header on the sidebar or on the folder but without the header the sidebar or the folder be aware of the content itself interesting let's see how we can implement such a thing so before i even get started everything we're doing here basically is javascript even those templates on those views i mean the bottom line everything is javascript and if i'm going to write some logic i might want to do it inside of service because its logic is that it's not like rendering logic i'm not dealing with templates per se i'm not going to create any markup i do want to manage objects those view objects i'm going to create a directory i'm going to call it the portal because that's what we're going to build inside of it i'm gonna create a service so angular a service let's call this service uh well a portal a portal service let's hit okay let's check out this portal service let's talk about it what i want to do here i want to be able to manage views i wanted to be able to attach views into different places the first thing then then i'm gonna i'm gonna build here i'm gonna create a javascript map and call these targets and it's gonna be a map of string as a key and view container ref as an as a value right inside my constructor i'm gonna initialize this map by just creating again a plain javascript map so we've got a map and we can save stuff to this map the first method that i'm going to implement is how you add a view container to this map so let's call it well add target give me a target give me a target name which is a string and well give me a view container which is a view container ref all right and what i'm going to do here i'm just going to take these targets and i'm going to add item i'm going to set item sorry i'm going to set item and i'm going to take this target name and i'm going to take this view container so i'm just saving it into the map all right on the same on like on the same manner i'm gonna create a private method that's gonna help me get a target out of this map and i'm gonna implement two more methods one is attach and clear attach take a target name and this time it's take a template and then he goes to this map of targets looking for a view container and create a view out of this template clear taking a specific target and just clear it i'm going to share this code with you so don't worry but just have a quick look i created a map of view containers and i've got a methods that can get a template and attach it to a specific view container everything is managed inside of a service all right the next thing that i'm going to do i'm going to create two directives i already prepared them ahead because it's a short talk i don't want us to mess too much with the live coding when it's not necessary i created two directives i'm going to add them to my module otherwise that's not going to work so one of them is there attach to directive and the other one is add target oh sorry let's do it like the right the right way the other one the other one is target uh which are we ma forgot the name yeah just target directive cool and why do i need an attach directive entire directive let's see how how it's implemented the target directive it's a directive that you can put everywhere you want you provide a name it will create a view container ref and then use my service to add this target to the map the attach to directive you can put it on any template that you want specify the target name and it's gonna call the service and attach this template to a specific target name what does it mean in practice let's say that my homepage wanna render something on the header so i can create an ng template i can use the attach to directive and say i want to attach it to the header let's create here a button home button all right so my home page gonna attach this to the header and because i'm inside of my home component i can also implement and click let's call it home and it's not going to do much you're just going to alert home on the other hand my profile component want to attach something to the header but this time it's going to be something to relate it to the profile let's call it get profile so each page can render sorry each page can render stuff on other places let's add here just a quick another one attach this to the folder and this time just attach an h5 says uh profile say hello each page on each page i can send some stuff to render in other places well how can i achieve this in the header in the head in the header i can create an ng container and use my target to head this place as a target let's call it header it's supposed to be a string right and i can add a target to the footer itself let's call this target footer let's go back to the code and see if i was able to achieve something or just a lot of mass yeah it's missing types of compilation blah blah blah let's fix it and end this talk with this amazing demo so here we've got a h2 i've got a target directive uh tp target that's okay the header tp target that's okay the footer tp target that's okay too uh actually let's just do an ng serve again maybe i just missed something in the compilation it should be quick there's nothing literally nothing on this project cool let's go back here and let's see what's going on i'm on the homepage i see the home button i'm on the project page nothing happened i'm on the profile page i can see the profile and i can see the profile say hello so basically each one of the pages can render stuff dynamically we just prove you that the view hierarchy doesn't mean dom hierarchy i know it was quick my time is like disappeared so i'm gonna end this talk uh i'm gonna share with you this code and this demo so we can play with it and obviously you can reach me out for more questions so what we learned we learned about the view container we learned some new language we learned how to manipulate angular the right way it was quick but hopefully you learn something out of it you're more than welcome to keep in touch i want to thank you all i'm going to share the link to the code but if you can't wait for it check near that live send me something on twitter shoot me an email and hopefully uh i'll meet you in person on the next conference so again thank you hope you enjoyed it and learn something new see ya
Info
Channel: EventHandler
Views: 2,619
Rating: 4.9000001 out of 5
Keywords: js vidcon, jsvidcon
Id: 5AWh6Qhp-7s
Channel Id: undefined
Length: 32min 25sec (1945 seconds)
Published: Sun Nov 01 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.