
Angular Templates: Start To Source - Learning how Angular works on the inside
Angular Templates: Start To Source - Learning how Angular works on the inside
Ever wondered how Angular keeps track of how things are rendered? Well, it uses views and templates to do so! This talk walks through what views are, how templates work, and how you can utilize them in your codebase today.
This talk is the companion to an article on our site:
https://unicorn-utterances.com/posts/…
This talk was given by Corbin Crutchley:
/ crutchcorn
For more info or questions, feel free to read through the article or join us on our Discord:
/ discord
Content
0 -> later so this is angular templates start
3.33 -> to source a little small disclaimer a
5.79 -> lot of this dydz really in deep into
8.639 -> angular if you're not familiar with
10.11 -> anything it's okay please feel free to
12.36 -> ask questions please feel free to kind
14.82 -> of stop the talk address what you want
16.74 -> to address and we can move forward from
17.94 -> there just don't feel discouraged
20.49 -> whatever happens Sam so Who am I I'm
25.38 -> Corbin Crutchley I work for Hilton uh I
27.689 -> don't represent them literally at all it
30.3 -> makes no sense
31.14 -> I write react every day for my job but
34.41 -> yet somehow I'm here talking about
35.7 -> angular I did angular at my last job for
38.969 -> about two and a half years I was kind of
40.29 -> like our angular expert on the team
43.02 -> I collect retro give video games I have
45.27 -> everything from the Atari 2600 to the
47.34 -> Nintendo switch and I just I love open
50.64 -> source I think I have like seven hundred
52.25 -> contributions this year so what are we
56.43 -> gonna be talking about yes no and your
61.92 -> je s is the totally different piece that
63.93 -> I will not touch that's not true it's
68.13 -> not that I will not touch I just have
69.72 -> not gotten around to it and given that
71.85 -> it's being depreciated soon I don't
73.439 -> intend to live back so yeah angular 2
78.03 -> plus so I think eight is released I
84.299 -> think 9 is either releasing soon or just
86.34 -> released so what are we going to be
89.549 -> talking about we're gonna address what
91.56 -> angular templates are how you can
93.42 -> utilize them how angular works under the
96.15 -> hood a little bit so not just from a
98.28 -> code standpoint but we're also gonna
99.99 -> touch on some of the theoretical things
101.549 -> that angular deals with in order to show
104.07 -> and display and manage UI code we're
106.649 -> gonna write some structural directives
108.21 -> if anyone's use ng for ng if we're
111.27 -> actually going to be looking at some of
112.439 -> the source code implementations from
113.85 -> angular we're just gonna have a good
115.92 -> time try to figure out what all this
117.84 -> stuff is about including me I wrote
119.729 -> these slides a while ago
120.95 -> so let's start with a bit of background
124.409 -> so angular has these concepts of
127.409 -> something called a template you build a
129.479 -> template using an NG template tag like
132.18 -> here lines one through three and by
135.54 -> default without line four on the screen
137.64 -> it will not render so nothing from lines
140.64 -> one two three will render unless if
142.56 -> something explicitly tells a template to
144.75 -> render in this case the ng-if tag will
148.709 -> render this so long as bool here is
152.43 -> false within the logic so if boolean is
156.03 -> false it will display the paragraph tag
158.43 -> false otherwise it will display the
160.5 -> paragraph tag true worth mentioning the
165.12 -> false temp here which stands for false
167.22 -> template is what's called a template
169.14 -> reference variable and it's how we're
170.91 -> passing the value of this template into
173.79 -> the ng if online fort here outside of
177.239 -> just having ng if to be able to kind of
179.94 -> explicitly declare that we want a
181.62 -> template to render we can also utilize
182.94 -> another template and an input called ng
186 -> template outlet here in line one we're
188.94 -> doing the same thing where we're
190.049 -> declaring a template and we are
191.549 -> assigning it to a template reference
193.47 -> variable called unicorn's then later
195.66 -> when we're using the ng template outlet
197.88 -> we're also rendering that same reference
200.31 -> variable to be able to showcase it on
202.92 -> the screen so that's the explicit render
205.23 -> mention we also have the ability to have
208.56 -> something called context much as a
210.51 -> function has the ability to pass in
212.34 -> inputs to a function we have the ability
215.1 -> here to pass in arguments of sorts into
218.549 -> a template so it's the second argument
221.79 -> or I'm sorry it uses ng template outlet
224.519 -> context to be able to provide an object
226.68 -> this object has a set of key value pairs
229.79 -> one of those keys is implicit and it's
233.22 -> what's marked as kind of the default
234.6 -> export so you know export default on es6
238.62 -> and in that case we're binding to a
240.81 -> template input variable called message
243.03 -> here which we can then display so in
245.639 -> this case we have the implicit key which
247.68 -> is hello world
248.43 -> we have person name which is Corbin
249.93 -> we're binding person name to the
252.569 -> template input
253.59 -> this person's name and we're binding the
255.84 -> default implicit value to message so if
259.23 -> we look at how this is rendered out this
263.49 -> is going to be some terrible screen
264.81 -> crunch but come on but we can see the
274.26 -> code is exactly the same and where is my
279.24 -> preview I don't know where my preview
287.19 -> went oh that's why okay and the preview
291.54 -> is available to be seen here which is
293.46 -> hello world Corbin well small
301.4 -> so we also have the ability to gain a
305.06 -> reference to this template from your
307.46 -> application logic so within your class
310.19 -> component you're able to use the view
312.86 -> child decorator on a property name to be
316.22 -> able to gain reference to it in this
317.63 -> case we're wanting to gain access to
319.759 -> hello message we're then using view
322.61 -> child and the name of that template
324.65 -> reference to be able to store that
327.47 -> reference into a logic property called
331.88 -> hello message template and then just to
334.07 -> showcase that it is showing properly
336.26 -> we have ng template outlet to explicitly
338.69 -> render that template with a different
340.61 -> variable name from the logic rather than
343.16 -> from the template itself but view child
347.72 -> isn't just for templates view child is
350.81 -> also able to gain reference to a
352.849 -> component itself so in this case if we
355.61 -> have a component say my custom component
358.849 -> with an input that says 50 we can use
362.33 -> view child on it using the same template
365.15 -> reference variable trick and in the ng
368.03 -> after view in it we're able to
369.56 -> console.log the input value to that
372.38 -> component so just to take it a tiny bit
376.22 -> of a deeper look what's happening is
378.83 -> that we have an input here on this
382.25 -> custom component and angular guesses the
385.82 -> type based on where the template
388.789 -> reference variable is so if you look at
391.01 -> the typescript definition type we're
392.69 -> actually gaining access to the variable
397.13 -> type a component class type itself and
399.65 -> that's why we're able to access the
401.87 -> variable name from the component
403.639 -> instance we're also able to why is that
411.56 -> not doing the thing sorry
419.1 -> we're also able to overwrite the assumed
421.78 -> type so let's say that we want to gain
423.85 -> access to the underlying HTML element
426.31 -> rather than the class component instance
428.38 -> itself what we're able to do is we're
430.54 -> able to use this read proper on line 13
432.85 -> to tell angular explicitly hey I want
436.6 -> reference to the underlying element that
439.06 -> this HTML component is rendering to
441.46 -> rather than the component instance that
444.19 -> this element is associated with so for
446.59 -> example if we have a data set attribute
448.93 -> which is on line 7 called in this case
451.72 -> unrelated attribute we can console.log
454.72 -> this attribute from the native element
457.99 -> itself rather than from the class
460.17 -> instance so we're overriding what assume
463.18 -> type angular has on that component
465.67 -> instance yes so on
471.66 -> exactly so I'm not I'm not accessing the
474.34 -> the class instance I'm in students right
477.31 -> yeah exactly
479.05 -> so what's nice here is that we're able
481.27 -> to access both the instances on the dom
484.21 -> and within the class itself
487.32 -> there's also view children which is very
490.42 -> similar to view child but is able to
492.64 -> access more than one element so in this
495.19 -> case instead of querying a template
499.6 -> reference variable we're now referencing
501.85 -> the class instance name itself and that
504.73 -> class will go find all the instances of
507.25 -> that component that are on the screen
508.72 -> and you're able to treat it almost as an
511.54 -> array it's an array like so in this case
514.24 -> we're able to see that once the
516.18 -> component renders we're able to see hey
518.77 -> we have two elements on-screen that
520.75 -> match your query because it isn't an
524.29 -> array and it is an array like we can
526.33 -> also do some interesting things with it
528.31 -> in this case we're subscribing using
530.86 -> rxjs observables whether or not a
533.71 -> component is changed or if this query
536.32 -> updates in any way in this case on line
539.23 -> three and five we're wrapping one of the
541.78 -> components inside of an NG if to
543.61 -> conditionally render it when the
545.86 -> checkbox on line two is changed
548.32 -> this will render and not and every time
551.62 -> that this component implementation does
553.84 -> it will randomize an internal property
556.45 -> called number prop and it will calculate
558.7 -> the sum of all of the components
561.87 -> together in order to showcase so look at
565.78 -> that code really quickly we can see that
573.19 -> number prop is a randomized number
576.49 -> property that is floored every time a
578.47 -> component is instantiated and it just we
582.4 -> just want to be able to console.log the
586.57 -> combination of every item that's on the
588.82 -> screen so once this renders we can see
593.77 -> that each of the values of these
595.15 -> components changes and when it does were
597.91 -> able to get the sum of both of them that
599.95 -> are on the screen and that's because
601.72 -> we're able to subscribe to Dom changes
604.15 -> whenever it renders we also have the
610.93 -> ability to embed views directly from
613.39 -> logic so what we were doing previously
615.97 -> when we were using one ng template to
618.58 -> show another on the screen is we were
621.07 -> actually embedding it so when you embed
623.35 -> a template it creates a view and what
625.9 -> we're able to do is we're able to do
627.7 -> this manually from within the template
630.01 -> logic rather than using an NG template
632.2 -> outlet so what we're saying here is we
635.2 -> want to gain access to a view container
637.57 -> reference using the template reference
639.64 -> variable a view container is simply a
642.31 -> way that we can read an element and
645.1 -> treat it as a place to be able to inject
648.81 -> views so when we want to render a
651.43 -> template we have to have a view
652.69 -> container to inject it into when we use
655.15 -> ng template outlet this is kind of
657.28 -> magically handled for us and your hides
659.2 -> a lot of the implementation but this is
661.3 -> how it works under the hood where we're
663.34 -> using view child to get a template
665.62 -> reference to line four for the temple
668.5 -> template reference variable and then on
671.44 -> line 23 once this temp component
674.59 -> initially renders then we're going to
676.63 -> inject a view so it will show
679.1 -> item 1 list item 2 inside of the div
682.07 -> that's on line 10 with class testing
688 -> this same view container ref is also
691.85 -> able to pass in a context so I know that
695.27 -> I touch on context a little bit earlier
697.16 -> and instead of ng template outlet
698.96 -> context we're able to pass in a second
701.33 -> property to the creating that'd view ref
703.61 -> method so just so that we can get a kind
706.97 -> of holistic perspective we can see we're
714.38 -> getting reference to the view container
715.97 -> and then we're creating embedded views
719.57 -> with an implicit tag that implicit tag
722.54 -> is then bound to the default input
725.33 -> variable I and then we're showing eye on
728.78 -> the Dom so if I open up the element
731.81 -> inspector which is far too small we can
735.89 -> see that the unordered list now has two
738.65 -> children inside of it because we're
741.29 -> looking for the view container and
742.64 -> rendering it there
749.05 -> view containers have limitations though
751.37 -> angular does a really good job at hiding
753.86 -> a lot away a lot of its implementation
756.32 -> detail but two of the things that
757.94 -> angular cannot do is within a view
761.48 -> container it cannot move elements and it
764.09 -> cannot change the number of elements so
765.71 -> it cannot render or hide an element but
768.62 -> that doesn't seem right right we just
771.86 -> showcase that we can conditionally
773.27 -> render an element so how is that being
775.19 -> done and the way that that works is that
777.67 -> under the hood angular is utilizing some
780.86 -> of these api's on the view container to
783.26 -> be able to inject new views remove views
786.17 -> every time that we want to show or hide
788.18 -> an element so it's really kind of hiding
790.79 -> away a lot of the issues that are
792.53 -> inherent to the system that's been built
794.48 -> in this case we have the ability to move
797.21 -> a template so if we have an embedded
799.79 -> view that we've put in the wrong order
801.95 -> so instead of saying 1 2 3 4 it will now
805.13 -> say 3 4 1 2 we're now able to move the
809.66 -> incorrectly placed a view up 1 2 render
814.01 -> properly as 1 2 3 4 we can also insert
819.86 -> templates directly so if we know the
822.44 -> index that we want to create we can
825.2 -> manually create a view instead of
828.23 -> embedding the view and then we can
830.21 -> manually insert that view into the view
833.09 -> container so the template allows us to
835.94 -> be able to have methods on it that will
838.07 -> create a view that is not instantiated
840.29 -> in the Dom but is kept in memory and
843.44 -> then you can tell it to insert that
845.66 -> memory view directly into your DOM and
849.1 -> this is actually how create embedded
851.66 -> view on your view container works
853.4 -> directly with an angular so this source
855.02 -> code is taken from angular 8 and all it
857.51 -> does is it creates a template view in
860.18 -> memory it inserts it into the Dom it
862.58 -> returns a reference we also have the
867.05 -> ability to manage and modify templates
869.81 -> directly from directives so under the
872.81 -> hood directives are just a very actually
875.57 -> components are just a very complex form
877.58 -> of
879.199 -> and as a result we're able to do a lot
881.24 -> of the create embedded view this is so
883.639 -> fuzzy I apologize we can embed views and
887.269 -> we can create views directly from a
888.769 -> directive rather than from a component
891.379 -> itself so in this case we have an NG
894.35 -> template we have the directive render
896.689 -> the template which is marked by the
898.369 -> selector on line two we're gaining
901.699 -> access to the content child which is
905.3 -> kind of like a new child but for
906.439 -> elements that are nested inside of the
908.389 -> selector we're getting the template
910.579 -> reference here we are then getting the
914.6 -> view container ref from the dependency
917.209 -> injection and creating that view and
919.759 -> injecting it directly into our code so
923.869 -> view containers are able to be created
926.24 -> kind of invisibly without having to use
928.399 -> a view child using the dependency
930.47 -> injection system angular knows that you
932.36 -> want to inject a template when you ask
934.399 -> it for a view container so it goes ahead
936.259 -> and creates one under the hood we also
940.85 -> have the ability to get a reference to
943.67 -> the element itself so if we have an NG
947.839 -> template on line 20 we're able to use
950.119 -> that same dependency injection trick to
952.279 -> gain access to the template that the
954.22 -> very the directive rather is on and
958.699 -> we're able to render that directly
960.47 -> instead of having to have a wrapper at
962.24 -> content childhood so this is a fairly
965.569 -> useless implementation of a selector
969.649 -> because it doesn't do anything here but
972.439 -> because it is a directive we're also
974.929 -> able to have inputs just like any other
977.629 -> directive would have so in this case
979.819 -> we're adding a directive for that has
983.839 -> the same selector name so we're able to
985.639 -> just bind it as if it is an input on the
988.249 -> div or the ng template here we're
991.069 -> accepting a string and we're passing it
992.869 -> as the implicit value to the context so
996.139 -> in this case this would say it would be
999.17 -> a paragraph tag that says hi there
1001.089 -> because we're binding the context
1005.639 -> we could also since we're on the pattern
1009.19 -> of rendering templates and adding in
1011.019 -> context what if we just made a totally
1013.149 -> separate context that allowed us to pass
1016.3 -> in an object for your context and the
1019.12 -> name of a template reference variable
1020.86 -> and suddenly we're left with an API that
1025.75 -> looks rather familiar from the beginning
1027.61 -> of the talk
1028.329 -> think ng template outlet in this case
1031.809 -> we've renamed it to render the template
1034.03 -> and it contains one input that contains
1036.73 -> the template reference and another one
1038.47 -> that contains the context and we're able
1041.169 -> to render the name of another template
1043.39 -> with a context and we've just recreated
1047.319 -> some angular source code for NG template
1049.84 -> outlet we can do one step further though
1054.34 -> so additionally to the idea of
1057.299 -> directives there's also something called
1059.47 -> a structural directive which I hinted at
1061.24 -> that at the beginning if you if you've
1063.28 -> used ng if ng for any of the built-in
1066.49 -> utilities provided by angular you've
1068.799 -> already used some of these before in
1070.48 -> this case what it does is it wraps the
1074.14 -> element that these structural directive
1076.15 -> is on inside of an NG template so if we
1080.83 -> look at line 20 all we've done is added
1082.84 -> an asterisk to the render this and we're
1085.57 -> using the dependency injection trick as
1088.09 -> before so we haven't modified a lot of
1090.13 -> the code for the render this directive
1091.78 -> from some of our previous examples the
1094.21 -> only difference is instead of having to
1096.19 -> have it be an NG template and then a
1098.02 -> paragraph tag now we're adding an
1100.03 -> asterisk to imply to angular hey please
1102.61 -> wrap this in our directive wrap this in
1105.22 -> an NG template and what's nice is that
1107.34 -> because all the asterisk is doing is
1110.23 -> wrapping it in an NG template under the
1111.909 -> hood we can actually apply it the same
1114.13 -> way we did before where we're just
1116.38 -> adding render this directive on to an NG
1119.86 -> template and just rendering that out
1121.87 -> right
1125.68 -> so in this instance we can do a very
1129.1 -> very rudimentary form of the ng-if
1131.56 -> structural directive where if on
1134.85 -> initialization the input to that
1137.32 -> directive because again it is just a
1139.18 -> directive is false it will not render
1141.61 -> but if it is it will create a view and
1144.13 -> embed that view directly the problem is
1148 -> whenever you go to update that you're no
1150.94 -> longer initially instantiating that
1153.82 -> directive so we'd need to do something
1156.16 -> like this where our input is a setter it
1158.23 -> runs an update function and this
1160.63 -> conditionally either clears the virtual
1164.25 -> sorry the view container or it will
1167.5 -> create a new reference so in this
1171.34 -> instance I'll add a console.log here so
1179.98 -> we can see that when I'm updating this
1182.68 -> value this setter is ran it runs the
1186.49 -> update and now we're able to
1189.7 -> conditionally render an item on the
1191.47 -> screen using nothing but a home-brewed
1193.48 -> version of ng-if and again this is a
1199.75 -> much more ok I now don't have internet
1202.33 -> connection that's fine but the the
1208.48 -> concept is the same
1211.35 -> exactly
1214.34 -> if anyone's used ng4 for more complex
1218.51 -> instances as anyone used something like
1220.36 -> a let number of numbers semicolon first
1226.1 -> equals first has anyone used something
1227.63 -> like that or let index equal index
1230.26 -> anything no okay
1233.15 -> well micro syntax is a way that you can
1237.29 -> have very verbose directives without
1240.86 -> having to have a bunch of inputs on the
1243.08 -> item itself so in this case we have our
1246.74 -> input which is bound so we need to make
1249.32 -> this selector and the setter match the
1252.2 -> same name and if we're able to do that
1254.33 -> we can pass in a value directly excuse
1257.9 -> me but we can also bind the context
1260.84 -> directly so in this case implicit
1262.79 -> becomes message so we've just made a pig
1265.55 -> latin structural directive which will
1267.98 -> make any message into Pig Latin we're
1272.21 -> also able to pass in named context
1274.49 -> values so if you remember towards the
1276.05 -> beginning person name was a named export
1278.78 -> on the context we're able to do so here
1281.39 -> as well so original message is just
1284 -> bound to a new key in the context that
1287.72 -> key is then referenced by name and now
1290.42 -> we're able to use this so the message
1292.88 -> this is a string is whatever the pig
1295.85 -> latin version is in pig latin we also
1301.16 -> can have multiple inputs so let's say
1303.2 -> that we wanted the ability to have an
1304.67 -> uppercase or a lowercase message of pig
1307.25 -> latin we can pass in casing which is an
1310.94 -> input for upper lower case so now we
1314.15 -> could go even further so the message
1316.73 -> blank is original message in upper case
1320.15 -> pig latin so we can really take this API
1322.97 -> and make it very very verbose and all
1325.91 -> that means is that we just have to
1327.35 -> preface casing with make pig latin
1330.23 -> casing so it's just a little bit of
1332.33 -> naming convention we're able to utilize
1334.31 -> this very powerful syntax there's also
1339.14 -> the as keyword which if anyone's dealt
1341.66 -> with asynchronicity and anger you've
1343.73 -> probably
1344.2 -> come across this at some point where let
1348.6 -> this observable pipe async as whatever
1352.57 -> and then utilizing that elsewhere
1355.21 -> we're able to expand that here it allows
1360.97 -> us to be able to get the value from an
1362.62 -> input so in this case we can have the
1364.75 -> uppercase version of the message save
1366.49 -> just by passing in a pipe which to
1370.45 -> clarify this uppercase pipe is not
1372.309 -> something that I've done this is built
1373.75 -> directly into angular it allows us to
1376.149 -> store values directly from within and in
1382.57 -> order to make this work all we have to
1384.279 -> do is we have to return the name of the
1387.61 -> input as the same thing so in this case
1389.73 -> casing upper upper case we can just
1393.37 -> return the key make Pig Latin casing and
1399.37 -> it will allow us to be able to preserve
1400.96 -> what upper pipe upper cases so in this
1404.679 -> case it would be like upper with all
1407.679 -> caps the one thing that is quite
1412.96 -> interesting about the micro syntax is
1415.09 -> that it's very versatile all of these
1417.399 -> are valid some of them have semicolons
1419.74 -> some of them don't have semicolons some
1421.269 -> of them are arranged in different orders
1422.889 -> all of those are valid though that is
1427.72 -> the actual reg X that's used for testing
1431.529 -> whether a micro syntax it's real it is
1434.309 -> big
1435.7 -> jargon s and confusing it's a little
1438.07 -> more structure than clear here where the
1440.95 -> colons and semicolons are optional in
1443.11 -> order to bind certain things you can use
1444.58 -> specific keywords but this is much more
1448.059 -> intended as an in depth when getting
1450.82 -> further into micro syntax so let's see
1455.59 -> if we can apply everything that I've
1457.12 -> discovered here let's see if we can
1459.1 -> remake ng 4 we've already done ng if
1460.96 -> let's do ng 4 but some ground rules
1463.179 -> because the ng 4 API is way too
1465.85 -> versatile there's way too much in it
1467.62 -> that I'm not going to cover right now
1468.639 -> and I'm not going to worry about garbage
1470.32 -> collection I'm not going to worry about
1472.269 -> updating the array cuz that adds some
1474.119 -> additional fun complexity I just want to
1477.089 -> be able to use the syntax very similar
1478.829 -> where I want to see if an item is the
1481.289 -> first item lender each of the items in
1484.529 -> that array so I have some code here that
1490.859 -> I'd set up as just a basis I want to be
1494.909 -> able to have a syntax very similar to
1496.559 -> this so let me copy that drop that in
1502.709 -> and it's immediately going to complain
1506.009 -> about the thing that I'm gonna fix so if
1509.489 -> I add in first let me go over what I'm
1512.249 -> doing so I want to be able to use an
1517.189 -> async pipe on this numbers observable
1522.479 -> this numbers of zero volt is going to
1525.289 -> return an array and we want to be able
1528.329 -> to render each of these items in the
1530.189 -> array as number number in a list of and
1535.499 -> the number of numbers and then that
1538.739 -> actual number itself and if it is the
1540.959 -> first item we also want to add the
1542.669 -> message it's the first number so this
1546.059 -> line 19 is the syntax that we're going
1548.459 -> to use to do so so we have let number of
1552.929 -> numbers so I need to add the of keyword
1555.179 -> so I'll do input uni for of and that's
1561.509 -> going to be an array I'm also going to
1567.419 -> double check that I am correct
1569.249 -> by implementing after view in it
1585.55 -> so if I look in my console logs I can
1587.74 -> see that that was an array in order to
1590.89 -> create the elements on string on screen
1593.71 -> I'm going to create a constructor I'm
1596.65 -> going to get an instance of the view
1599.62 -> container ref and the template that it's
1603.22 -> on I'm going to this dot unifor thereof
1612.76 -> so for each of these items I want to
1618.85 -> create a template reference and be able
1621.97 -> to create a view so in this case I'm
1624.31 -> going to do this VC create embedded view
1629.26 -> I'm going to pass in the name of the
1631.84 -> template and I'm also going to pass in
1634.42 -> the context so we can see that it's now
1637.45 -> rendered the proper amount of time and
1639.72 -> now I can pass in the number of course
1646.18 -> it's going to fail on me for unrelated
1647.59 -> reasons
1653.21 -> I'm gonna edge case that for now so now
1656.49 -> we can see that even though the numb of
1659.07 -> the full sorry okay
1661.5 -> now we can see that even though the full
1663.24 -> list of numbers isn't rendering we can
1664.86 -> finally get one two three four five
1666.57 -> which is the expected output of this
1668.85 -> async I want to be able to see if an
1672.9 -> item is the first item so is first is
1676.049 -> the name of the key that I need to pass
1677.58 -> and that's easy enough I can pass in an
1681.09 -> index key so is i0 so now we have that
1688.71 -> working and finally we can return the
1695.63 -> Uni for of as this dot uni for of and
1703.549 -> now it should finally list how many
1705.99 -> numbers there are so just within a few
1708.6 -> moments granted I've practiced this once
1710.91 -> or twice but just within a few moments
1712.799 -> we're able to make a fair implementation
1715.02 -> of the ng four which allows us to be
1718.679 -> able to just take this code and just
1720.419 -> expand it into this very very powerful
1722.4 -> tools with built-in support for
1724.64 -> observables yeah so it's a very powerful
1730.049 -> tool once you understand a bit more
1732 -> about templates that's what I have for
1737.46 -> you so I did a much much much more
1741.69 -> in-depth dive that covers how Angoor
1744.48 -> kind of handles some of the stuff
1745.89 -> internally admittedly those slides I
1747.96 -> thought were in this version of the
1749.4 -> talking we're not but if you go to
1752.19 -> unicorn uh pterence is there's like a 55
1754.44 -> page post about all of this stuff that
1756.69 -> explains much more feel free to reach
1759.6 -> out feel free to ask questions it are
1762.33 -> there any questions
1767.75 -> sorry so there was an instance in our
1773.7 -> code for my last project that was
1776.37 -> perfect for a structural directive it
1778.86 -> required both templates it required the
1780.93 -> ability to conditionally render but I
1782.88 -> also wanted to have all sorts of
1784.35 -> additional logic in there so I wanted to
1785.94 -> go make a network request I wanted to do
1789 -> XYZ and then I wanted to render a
1791.4 -> template in that template had to depend
1793.11 -> on a bunch of different things that's
1795.87 -> when I finally had kind of had to learn
1798.93 -> what a structural directive is why it is
1801.06 -> and how to utilize it because I was
1802.92 -> trying to make a component API system
1804.84 -> for my co-workers who were less familiar
1808.35 -> with the way that a lot of angular
1809.94 -> worked internally and from there I
1813.18 -> started writing a blog post to launch my
1814.98 -> site and I just kind of dug in deeper
1816.84 -> deeper deeper and funny enough a lot of
1819.78 -> this stuff anything about templates
1821.34 -> anything about structural directives
1822.84 -> there is either extremely little one or
1826.08 -> two sentences or no code documentation
1829.11 -> whatsoever this regex looks absolutely
1832.65 -> ridiculous can we all can we all agree
1834.39 -> at very least that this regex is bananas
1836.88 -> and should not have been marked as
1838.41 -> documentation that this regex
1843.57 -> and it's not real regex by the way but
1845.52 -> this regex no joke for two years was the
1847.95 -> only official documentation on how micro
1850.56 -> syntax worked period even now this
1853.89 -> stands as a majority of the
1855.54 -> documentation that exists within the
1857.01 -> official angular templates so I wasn't
1860.49 -> very happy with that and their official
1862.26 -> line is well if you want to learn it go
1865.41 -> read the source code and no joke I've
1867.81 -> seen that line referenced directly in
1870 -> documentation through messages with
1871.8 -> maintainer is it it's kind of there at
1873.63 -> their underlying
1875.23 -> sure it's not you you and I both know
1879.62 -> it's not so so the reason why the blog
1883.34 -> post is 55 pages is not because oh gee I
1886.19 -> really like writing 55 pages it's oh my
1888.799 -> God look at everything that wasn't
1890.75 -> documented so it was my best ability to
1894.86 -> try to document everything in the most
1896.45 -> structured way that I could I realized
1898.34 -> this talk was fairly fast paced I swear
1901.4 -> the blog post is better I solemnly swear
1903.559 -> it is there are 93 examples on that post
1906.4 -> but I have tried my best to condense a
1909.44 -> lot of information into a somewhat
1912.65 -> palatable talk so I apologize if it is
1915.169 -> fast yeah so that's kind of the reason
1921.679 -> why it's because they told me to don't
1923.809 -> tell me to go read source code I will
1925.99 -> and I'll teach everyone else how to read
1928.25 -> it to ah payback
1939.37 -> I'm wondering if I can add one more
1941.809 -> piece if that's okay with everyone it's
1944.48 -> gonna be somewhat ad-hoc and I swear I'm
1948.59 -> not doing this just to load the very
1950.51 -> pretty sight okay is everyone familiar
1957.169 -> with the Dom tree yeah okay so if you're
1963.08 -> not really quick recap this is what
1966.59 -> we're I'm gonna zoom in on that this is
1969.62 -> something that we'd see an HTML code we
1971.99 -> have a main tag we have an unordered
1973.7 -> list we'd have to list items and a
1975.89 -> paragraph as a sibling to the unordered
1978.53 -> list the way that this is handled by
1981.08 -> your browser is something like this we
1983.87 -> have a main tag as the top our child our
1987.169 -> the p and the unordered list and as a
1989.299 -> child to the unordered list we have to
1990.59 -> list item so it creates a memory tree in
1993.89 -> order to parse so when you do something
1996.08 -> like this and look for ID B children
2000.34 -> Ella alive it will go find B and it will
2004.03 -> go find the children Li to apply this
2006.61 -> CSS to write so the tree is really nice
2010.12 -> for being able to very quickly parse and
2012.13 -> handle things
2013.23 -> angular unsurprisingly has its own
2015.91 -> implementation the reason why you can
2018.64 -> store a view and these are the slides
2021.13 -> that I thought were missing and I don't
2022.27 -> know where they've gone the reason why
2025.63 -> you can have a view without embedding it
2027.85 -> directly is because angular keeps its
2030.1 -> own State it keeps its own tree of these
2033.13 -> views and the elements that are on the
2034.99 -> screen in order to render it is not it's
2038.26 -> actually not the shadow Dom nor is it
2040.419 -> really a virtual bomb you a lot of
2044.29 -> people think it's a virtual bomb and
2045.85 -> it's very very similar in a lot of
2047.559 -> practices the problem is there's no
2048.909 -> standardization on what that really
2050.59 -> means because of course there isn't but
2053.83 -> it is much more similar to a virtual
2055.75 -> bomb shadow DOM is just what this mental
2059.98 -> model allows for so we're able to render
2063.159 -> from angular to a shadow Dom because
2065.05 -> angular has these concepts of an
2067.149 -> immutable bomb structure which is why
2070.149 -> again you can't
2071.46 -> create or move views without either
2073.56 -> unrendered view or elements without
2077.01 -> changing a view in some way because it's
2079.409 -> meant to be this immutable structure
2080.82 -> that directly correlates to the Dom so
2084.57 -> in this case we have templates we have
2086.609 -> views that are referenced by templates
2088.53 -> and we're able to put in view containers
2091.29 -> so there's an element that is also a
2093.69 -> view container this view container is
2096.27 -> able to have a template which then
2097.71 -> renders a view so angular has its own
2100.2 -> way of having every time you create a
2102.869 -> directive or a component all the
2105.72 -> component is is a directive plus a
2108.42 -> little bit of sugar to add in a ng
2111.119 -> template and that's it that's the only
2113.52 -> difference between a directive and a
2114.839 -> component in angular is the concept of a
2118.17 -> host view which is just implicit magic
2120.93 -> and angular adds it for you a view
2123.48 -> container that is then used to render
2125.82 -> all of the children elements and it's
2128.13 -> why you can have a component that
2129.51 -> renders things conditionally gets very
2132.54 -> complicated after this charter I
2134.31 -> actually think that's the last part I
2135.75 -> made because it got it gets so like
2137.76 -> stupid ridiculous but angular uses these
2141.78 -> concepts of views everywhere whether you
2143.849 -> ignore it or not every time you use a
2145.859 -> component that's a hosts view every time
2148.2 -> you conditionally render something or
2150 -> even every time you update a Dom element
2153.15 -> using your input from logic that is a
2155.64 -> host and a view that is then just re
2158.88 -> rendering every time so it's how angular
2161.49 -> is able to track what you have in logic
2163.44 -> and it's how it knows what to go update
2165.93 -> because it already knows in memory where
2168.75 -> these items are and how to go access
2170.609 -> them
2175.41 -> it's very very similar and this is this
2179.29 -> is always the frustrating part is that
2180.79 -> if you talk to one of their devs
2183.48 -> actually to be fair both dev teams are
2185.65 -> very responsive and they're both very
2186.94 -> respectful to the other teams but if you
2188.38 -> talk to a lot of community members
2189.46 -> they'll go oh well they're not the same
2191.799 -> and there are very very specific
2193.619 -> implementation differences react doesn't
2196.569 -> actually have the concept of a template
2199.93 -> at all it just has an element so it's
2203.2 -> much more verbose in how one-to-one it
2206.109 -> correlates to an element angular
2208.599 -> provides like this abstraction on top of
2210.819 -> it to provide an immutable model and
2213.79 -> blah blah blah blah blah but really from
2216.069 -> a like a very high-level thousand-foot
2218.14 -> perspective they're extremely similar in
2220.329 -> that they both contain some form of
2222.43 -> memory that represents the DOM and a way
2225.04 -> to render into that Dom it's just very
2227.47 -> different how they do so under the hood
Source: https://www.youtube.com/watch?v=7AilTMFPxqQ