Angular CDK - Portal Module [Advanced, 2021]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello guys mr mozzansky is here and today we're gonna talk about model called portal this model comes from the library angular cdk and it allows you to render your ui really really flexible way watch this video until the end and you will see how to build the application which depends on the context can render different action buttons to interact with it's gonna be very interesting so let's get started to figure out what is portal all right we have got uh the application i prepared some skeleton for you and there is the very simple app where we have two pages users and orders there have some demi data which doesn't really matter for this exact case the interesting thing that we have this area called action area and depends on which page we are we would like to render different action buttons here at the right bottom corner and uh it might looks very trivial but there is one thing uh which doesn't make this task really so trivial it is that if we have a look at the component we will see that they don't have the parent-child relationships yeah they are located in different uh component tree hierarchy and our action area located here and this is the place where rendered our pages users and orders and i hope uh this is you are already aware how routing and i know services are working in angular because this is them that's a quite advanced topic and uh if you are new to angular i would suggest you to take some for beginners course and i would recommend you some really useful courses which you can find in the description to this video all right uh then let's continue and then second thing i would like to mention that i will add the link to the source code uh for this application so you can check out this and uh follow me follow this video and this initial state will be in the git so you can you can use it all right let's uh talk a little bit implementations so how we could uh solve this issue well there are different ways how to solve it with the different levels of insane i would say i'll show you the example of bad design without um portals and then we will implement another approach which is way more flexible and better by using this portal model and let's get started with the bad solution i will switch to the bad solution branch and yeah let's have a look how i implemented this so inside this action area if we open this i put such a ugly ng switch statement and we have different context like users and orders and depends on this context we render different buttons so you can see if the context is users we render the one button if it's orders we render different set of buttons and this context comes from the service which kind of bridge between these actions area and our components like users and orders and this service has such a method which called switch context where we can set different context and you can see that i'm using this inside the order page and users page so inside the engine only need i switch this context and also i uh because they're on the different levels we should somehow react on the i don't know uh click on the a new user button or the search um button we have to somehow handle this logic and we cannot handle this within these actions because because it will be really uh too too much responsibilities for this context so i delegate this logic to the appropriate page so if it's add new user so i delegate this to the user page and inside the user page i subscribe to this a new item event and depends on this i show some view or handle it somehow a different way so this is how it is implemented and you can see it in action so i go to orders as example and i see different buttons and if i go to users i see this one button and if i click i see the form like this so i can add the new button like this is working solution but it has a lot of disadvantages and the most important is which i find really a bad one is that we spread the functionality across multiple components and it leads to the situation when if you need to remove some action or add some action you have to also modify actions area component and also your users component or whatever component which provides this uh functionality which needs this action buttons and imagine for a second that this action area it's comes from the library which is being maintained by another team and this might be a problem yeah if you're in the big company and it's really headache sometimes to ping another team please implement me this and then i don't know then you ping pong these things across the teams that's really uh terrible and the other thing is that imagine if we would like to extend this functionality with another context like as example if i select this row i would like to see also some different buttons like remove this item or edit this item yeah that's easily can be this is a very common use case and if we want to have it we have to also introduce a lot of another context like users and then users and selected one item or selected multiple items this is like complexity will grow exponentially in this case and it will be a really headache to to uh to to not implement to maintain such uh such implementation such a features and uh well i would suggest you to implement right now with portals model and we will see which benefit it will bring to us so let's then close it and switch to the branch which i call a good solution so let's switch to this branch and let's start to implement it so i would suggest you to start with app model and first of all we have to import this portals model right so i will do it right now so you can see that it comes from cdk portal yeah by the way uh don't forget to install first this angular cdk then inside the action area we have to define the slot where we're gonna render this piece of ui so if you imagine the usual portal we always have some entrance and the exit and this exit will be this our um outlet and i will write here ng template and having this i can use the directive called cdk portal outlet and this outlet takes the portal itself and i will i will have this portal as observable and i will use async to subscribe to it and also let's go to the action area component typescript file and oops and we will create this property somewhere here and it will be observable with type not template portal all right and what next next we have to create the portal content itself and in order to do this i will go to the users page so right here and somewhere below so i will create the template here and also i will create the template variable and call it portal portal content here we go and here uh below i will um here between this ng template i will render the button and let's grab this button from from from here so i would like to have this fab fab button let's copy it here now i can paste it i'll just remove it because i don't don't really need it and i instead of bookmark i will render the add icon all right that's we have and now we have to somehow render this piece of ui in our slot and again if we um recall how looks these portals we have entrance exit and such thing called wormhole yeah and this wormhole this is going to be our service we will create a service which will like do this job will be act as a bridge between those two so i will use the nx console this is the really nice extension for vs code from nx team and uh they provide you kind of uh graphic ui for angular schematics it's really useful and i will call this service portal breach let's call it like this and i say that i skip test and now i can click this run button and it will generate the service for me and having this service let's add some functionality to it and i will suggest you to create the private property called let's say active portal and it will be the new subject your subject and don't forget to define the type to it and the type will be template portal here we go and another property i would like to provide is a public read-only property called portal and it will be active portal exposed as observable so we allow only read values from this stream but we don't allow to emit values in this stream all right and in order to emit some value to the active portal stream we will uh use um method special method for this uh like set um portal yeah set portal and it will take the portal itself and then we will do what ah we have to define type it is a template portal and what we do here we just say active portal next and pass this value here we go uh we are almost ready to go the next thing we just have to connect those to this action area with our users page and i will uh do it like this so first of all i will inject our service i will call it portal bridge and then i will assign to this portal i will assign the actually active active portal from our service and then inside the users page i have to i have to set uh the active portal right so i have to also inject our bridge portal bridge service here we go and here i have to set the portal make sense and how we set it how we get this portal so there are a couple of ways the first one is to create it manually so i will show you how to do it uh let's uh introduce the constant called the portal portal and here is the new template portal right and it asks us to provide a template reference and view container ref it should be quite easy first of all we have to get reference to this portal contact content right so i will use the view child for this new child and i will read this portal content and here will be portal content here we go and it's gonna be template reference template ref and oops and this is unknown all right that's what we have and we also have to inject them uh what do we have to inject ah view container reference okay view container ref all right we have now everything to create a portal so let's provide here this portal content and then the view container reference and now we have created this portal and we can we can set it as a as our portal and it complain ah okay it's obvious code is just too slow all right so we can save it right now and check how it works so i will go to our application and we can reload it and nothing had been rendered why cannot read property created embed view of undefined white can not so means that this portal content is undefined and i know why because yeah we're using view child right and we try to access the value inside this ng only need which is wrong actually because at this point of time it will not be resolved we have to use either ng after viewing it or we can say here that static true and if we save it and now reload we'll see this button here and also this is might be a cumbersome to create this everything so there is the easier way there is a special directive for it and we can actually remove this everything or we can wrap it inside some i don't know ng container g container and we could use the cdk portal directive all right and then we could just get access to this directive right here we don't need these we just have to access our cdk portal and here we can say that this is the cd portal type and we don't need this portal anymore we can remove it and instead we can use directly this portal content here and it will be working as it was working before and of course we can remove this injection and now we see that the same thing happens here and yeah we can navigate but here's the problem that it this button stays we don't want definitely to have it so we need to implement also uh on destroy lifecycle hook there below there will be ng on destroy there we go and once we destroy this component we want to also destroy this portal content so i will call detach method on it and if we save right now and check it we will see that it appears once we enter this page and it disappears when we leave leave this page so this is a very basic introduction uh how you can implement it then a few words about the event handling so if we as example uh want to handle the click event so let's call it click handler if we want to handle it we can do it directly in this component and something like let's just console log it for now just want to show you that it works um so now if i go to the users and i click button you will see that we can handle it from this component so in this case whole our logic is located in one place in this user's page component and the beauty is that if we want to add some new action or remove some new action we just removing it from here we remove it from our view or we can remove the whole button completely that's it that's everything what we have do we don't need to touch our action area we don't need to touch our bridge service because bridge service it's nothing to do with it it just proxies it just emits the portals which you need to render to the outlet and that's it so this is pretty much uh everything about um this uh model let's revert it now thought this uh template portal is the most i would say widely used uh type of portals there are also two and other ways how you can create a portal you can create a portal from component and also from some dom element and let me quickly show you how you can also create those portals as well so let's start with the i know component portal and the type will be component portal as well all right and now inside this um only and you only need a life cycle hook we can create just instance of component so let's create one i will use again the nx extension component i will call it action actions action buttons the model i want to define it inside the app component css skip test and now i can run it and it should build or create the component for me all right here we go these action buttons component has been created so i close this tab and um okay it wants to have a type so let's have the action buttons here this is the type of the component right and here we will create uh the component portal component portal and i just need to pass the on this action buttons component here we go like this and now i have to replace our portal components to component portal and it says all right it it's wrong type so let's extend also also our this um method and here will be component portal all right and the type let it be any and also we have to adjust this right here or even better we can extend extract this to to the type right type alias and i will call it uh portals portal just portal and we have to replace this everything here all right looks better now and this is i believe it right so we can reload the page and there's still our add button why what we have forgot for now remove this this click why why because we didn't save this component come on yeah right and we see now that instead of actions button uh we see the content of the component right and if we navigate away it says that attempting to detach a portal that is not attached to the host blah blah blah all right ah because yeah we have to detach the component portal here because uh our portal content our template portal was not attached so it says that come on um yeah now i go away and yeah this component portal was destroyed the last option is to use dom portal to be honest i have never used this i don't know in which use cases might be useful but still that we have it and it's good to have right so let's create a dom portal and it's gonna be dom portal all right here we go and there i will create one so dom portal new dome portal and here you have to define the element from uh from which you can you want to create the portal so let's create some section here and i will give that id to this like uh dom portal and i will say that this is or yeah this is a dom portal all right and i have to copy this id and then inside our ts file i will use the document and let's inject it document and document here we go and now we can just use this document which we just injected and use the method get element by id and paste our copy and paste it here and we have to also path here instead of component portal dom portal and again we have to adjust the type so it's going to be dom portal and now we can we see that the error uh has gone and again let's adjust it also here and now it should works properly yeah you can see this this is the dom portal which is yeah great as i said i don't know where you could use it but it's nice to have such an option and um also be careful with this dome because doc says that if you use this dom portal their directives which might appear somewhere here or components may no longer get updates okay so let's be careful here and uh what else i can tell you about this this is actually um yeah essential things now you know how to create different portals how to uh render this inside the outlets and yeah one bonus thing i will show you it's uh what if we don't have access to this action area as example if we um cannot add this cdk portal outlet right so we it doesn't exist but we have some section this example with id called i don't know actions what we will do in this case well we can create the outlet also manually and we can create it from our users page as well so i can go to our users page and create the portal outlet right there and how i can do this so let's first of all create a property and let's call it portal host all right and the type of this will be the dome portal outlet all right and then inside this ng only need we should uh assign to this portal host the new instance of dom portal outlet and let's have a look what we have to provide so first this is the outlet element this is the this um element where we want to render the our content that's what we have to provide so we need to go here and use our injected documents in order to get element by id actions and the rest what we have to provide this is the okay component factory resolver here we go then we need uh application ref here we go and then we need also injector let's inject our injector all right and now we can provide all these things here this component resolver factory then needs application ref and also injector here we go and once we created a dome portal instance we just say that and here we have to provide uh the portal which we would like to render there inside this action section so i will say that i would like to render our template portal so this oops so this portal content and i can save it and now i can go to my browser and i see it was rendered there and if we inspect this element we can see that it was rendered inside this section actions instead of our outlet which we had before instead this one right so we created this portal uh like inside our component and we rendered in that outlet this um action buttons which is really powerful and can make your application really really way more flexible and now the last thing we have to do is to destroy our um our portal host so i will just uh call detach on uh when we call ng on destroy right so when i leave this page it will be destroyed all right now i would suggest you to clean up this a little bit and implement the same for orders page and we can finish with this topic so i will revert our dom outlet i will remove this everything here as well because we don't need it we don't need component portal we don't need portal host we just leave this template portal i will remove this part as well and here instead dom portal i will define the portal content and here i also replace it with portal content here we go all right that we can clean up later on before to commit uh let's go to orders page and inject our uh service which called the portal bridge here we go and then uh let's set uh portal bridge set portal now we have to create this portal so i will use again view child for this and it's going to be cdk portal and i will call it park tunnel content this is gonna be cdk portal here we go and we have to provide this here also don't forget that we have to define it as a static true static true all right and now inside this orders page we want to create the view for our portal so what so what we want to render here we're gonna render here two buttons the first one is a search another one is the map doesn't really matter what the functionality are but yeah we have this two button for this uh context for order page and here we just need to do what ah no sorry we have to uh say that this is the cdk portal right like this and we have to also implement on destroy lifecycle hook right and there below i will implement this ng on destroy and here i just detached the portal content like this all right here we go and i believe we have to yeah we have to remove this and revert portal outlet and i believe now it should work fine so we're on the users page and we have this add new button if i go to the users yeah we see that they were rendered two action buttons here so i think uh that's it the only one thing here is that okay that's wrong wrong type here because yeah it is expected only template portal but we have the three different um three possible uh types of this portal so i have to import our portal from um where we defined this i probably didn't export this all right um that's was somewhere in the service i believe yeah and we have to export like this we can save it and now we could adjust this thing here so here we go it all right guys that was it i hope the information was useful and in your real application you will find the real use cases where angular cdk portal can improve your application make them more flexible this video became a little bit too long i tried to cover everything about this model but if i forgot something please write me in the comment section we can discuss this there of course subscribe to my channel if you find my videos useful and uh yeah stay safe take care and see you in the future
Info
Channel: Decoded Frontend
Views: 7,090
Rating: undefined out of 5
Keywords: angular cdk portal, angular cdk, angular cdk tutorial, angular advanced tutorial, angular advanced topics, angular material, angular tutorial, angular 10 advanced tutorial, web development 2021, angular 2021, Angular
Id: wPjVWeXSdqU
Channel Id: undefined
Length: 41min 5sec (2465 seconds)
Published: Tue Jan 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.