4 ms·
> Is there a standard way to define local variables in an Angular template so you don't have to repeat the same redundant expression again and again I usually
by mattlondon 7y ago
> Is there a standard way to define local variables in an Angular template so you don't have to repeat the same redundant expression again and again
I usually define something in the component, and reference that. If you need to lazily evaluate it you can just reference a function in the component (e.g. "...{{ someFunction() }}...", and have the function do whatever lazy work and/or memoisation you need there.
If you need things to be initialised before the template is ready, you can use one of the life cycle hooks - e.g. ngOnInit(). More details of the different hooks here: https://angular.io/guide/cheatsheet https://angular.io/guide/cheatsheet
... that said, it might be easier (depending on context) to "learn to love the bomb" and just rely on Angular's binding to update the template as soon as the value becomes ready after the template has rendered - i.e. don't sweat about getting everything ready before the template loads, just let Angular handle the data binding and let it update the tempalte when the value is ready. This is where the RxJS stuff really shines since you can forget about a lot of the sequencing and just let Angular handle getting the right value on the page when it becomes available. Unless you are doing long network calls or heavy computation, everything is usually in place by the time your brain registers seeing the page anyway so it mostly works out OK and no one notices any thrashing of templates going on under the covers (... although there is a part inside of me that dies when thinking about the performance/wasted CPU cycles).
> is there a way to easily define simple light weight macros ("snippet reuse") so you can repeat the same pattern in one or more components
I have also suffered this recently. I am not sure how this is "meant" to be done, apart from making everything a separate component. I guess the argument is, if you need to use something in multiple places then it is an ideal candidate to become a component. For these "lightweight" components I will usually just use inline templates for the component decorator (rather than referencing a separate HTML template etc), e.g.
@Component({selector: 'snippet-one', template:`<b>My First Snippet</b>`}) export class SnippetOne{}
You can put a load of them into a single "snippets" module, import the "snippets" module when you need it, and then simply include that where I need it in other templates with <snippet-one></snippet-one> and so on.
I agree though that sometimes it would be nice to just have a file you can just easily drop in where you need it.
- DonHopkins 7y agoThanks, that's great advice! Angular is really great when I can get away with just not worrying about the bomb -- it's amazing what little effort it takes (I just wish ng-component was spelled with only one or two letters). But there are still those things I'm used to being very easy to do in Genshi, that seem incredibly complicated in Angular, and don't leverage JavaScript. Granted they both have extremely different architectures, but local variables seem like a no-brainer, and lots of parts of Angular use them indirectly like ngIf and ngFor, but as far as I can tell, Angular just doesn't give you a pure direct form of ngLet that supports binding multiple local variables at once, for your own use. And ng-template is just weird. I get the impression that <ng-template> is actually just directly exposing some low level implementation mechanism, and wasn't specifically designed to be a concise, powerful, general purpose, easy to use templating system, or behave in any way like JavaScript. I keep trying to work my way through this otherwise pretty good tutorial: https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/ https://blog.angular-university.io/angular-ng-template-ng-co... >But besides that else template, the use of ngIf also creates a second implicit ng-template! Let's have a look at what is happening under the hood: <ng-template [ngIf]="lessons" [ngIfElse]="loading"> <div class="lessons-list"> ... </div> </ng-template> <ng-template #loading> <div>Loading...</div> </ng-template> >This is what happens internally as Angular desugars the more concise ngIf structural directive syntax. Let's break down what happened during the desugaring: >the element onto which the structural directive ngIf was applied has been moved into an ng-template >The expression of ngIf has been split up and applied to two separate directives, using the [ngIf] and [ngIfElse] template input variable syntax >And this is just one example, of a particular case with ngIf. But with ngFor and ngSwitch a similar process also occurs. At this point I'm starting to feel dizzy, like when Scorpius needs his cooling rod changed. https://www.youtube.com/watch?v=U7SS0YCWVGs https://www.youtube.com/watch?v=U7SS0YCWVGs But when I got to the stuff about ng-template with parameter attributes prefixed by "let-", and tacking ";context:ctx" on to the template outlet name, and then having to stick some instance variable into your component source code (which is usually a separate file), my eyes glazed over and my palm hit my forehead. It's like learning a whole new set of cult-like jargon and mythological concepts (Outlets??! Why so many layers of indirection and different names for the same thing?), instead of reusing anything I already know about JavaScript, simply to pass parameters to a template. Maybe this is just a bad example and explanation of ng-template, but I haven't found a better one yet. @Component({ selector: 'app-root', template: ` <ng-template #estimateTemplate let-lessonsCounter="estimate"> <div> Approximately {{lessonsCounter}} lessons ...</div> </ng-template> <ng-container *ngTemplateOutlet="estimateTemplate;context:ctx"> </ng-container> `}) export class AppComponent { totalEstimate = 10; ctx = {estimate: this.totalEstimate}; } That's how ZOPE METAL templates felt: it was such a big fucking ordeal to pass every single parameter through a named "slot", each wrapped in its own special outgoing and incoming namespaced XML tag, like COBOL with angled brackets. When it's all just clean simple Python underneath, but that's hidden from you, and you can't just use Python expressions and calling conventions, or XML attributes, or xpath, or define concise custom tags with attribute and content parameters, or write general purpose Turing-complete macros like Lisp.