You need to define a
<template> to be able to use it elsewhere in your app as a
TemplateRef. You can store these
TemplateRefs in a Service and then access them from any
@Component in your app.
Now, it is possible to create a service that can store templates. Create an injectable, exportClass TemplateService and this will just have a property of template, which is a map. Then to create the templates to store in here we actually have to create a component that basically contains all of our templates.
This will have a selector of TemplateStorage and an empty template for now. Then just exportClass TemplateStorage. Then make sure that's declared. TemplateStorage, and the template service is provided.
Then any template we put in here...so I'll create a template and give this a ref of header. I'll put an h1 in here saying "I'm a header." Then in our class we'd need to look that up, so ViewChild, look up the header. This will be the header template. Then in ng after viewing it, we can store the template.
To do that, we need to inject the template service first and then we can say this service template's set. The key can be header. The value will be this header template. Now we've looked up this template and stored it in here.
What we need to do now is actually put that template storage component in our main component or on the dom somewhere so that those templates are created and can actually look them up. Even though nothing appears here those templates are still hidden away.
Now, if I'd want to create a directive on here, I will just call this Surround and I'll create a directive. The selector of Surround, make sure and import that, exportClass SurroundDirective, make sure and declare that. Fix a typo and inject the template service as well as the ViewContainer ref and the template, so the template ref.
Now in ng after View and Knit, we can take our View, say this.view, create EmbeddedView, and use the service and get the templates and get the header. It looks like TypeScript here really wants me to type my map, so I'll go ahead and add that. Then my map knows that it has a string mapped to a template ref.
Now, when I hit Save we'll have "I'm a header" rendered out instead of the original 1 button. I can also render out in my Surround directive the original template or the template ref that came in from the structural directive. Hit Save.
Now, I'll have "I'm a header" with a 1 button beneath it and I could come and create another template in my template storage. We'll call this one footer and say "I'm a footer." We'll make this an h2. We'll look up the footer, call this FooterTemplate, store my footer template, and then in my directive I could copy this, paste it here, and now look up the footer.
Hit Save, and you'll see "I'm a header," 1, "I'm a footer," and that simply happens by dropping this structural directive on whatever element you want. Let's save here. Now, that stuff will be surrounding 2. We have 1, my Surround directive creating new stuff around the 2 button, and then 3.
The key takeaway is that if you want template refs so you can create fancy things this way, you'll need to actually store them somewhere and create them somewhere. The majority of the time your template refs will be coming from either a structural directive or an inline template that you wouldn't be sharing around your entire application.