Templates: The Declarative Boundary In short: You describe what the screen should look like for a given state. Angular works out which DOM nodes to touch. The moment you start calculating inside the template, you have crossed a line that will cost you later. Once you have decided where a component boundary goes, you need to describe what the user sees. In plain JavaScript you would find an element, change its text, add a class, remove a spinner when a request finishes. An Angular template removes all of that. It is a declarative boundary : you say what the UI looks like for any state, and Angular keeps the screen in step. Telling versus describing Two ways to update a collection centre's live status: Imperative — you give instructions: > Find the element with id . If is true, remove the class, set the text to "Truck Dispatched", change the background to green. Otherwise add back. Declarative — you describe the result: > Show this status banner whenever is true. In Angular you never call and never toggle classes by hand. You update state — usually a signal — and the template follows. The three core bindings The direction is consistent: data flows down through and ; events flow up through . Native control flow Older Angular used structural directives — , , . Angular's built-in control flow reads like the JavaScript you already know, and it is what the current documentation asks you to use. Here is a rendering the day's intake: The expression matters. It tells Angular which record maps to which DOM node. When one farmer logs a delivery, Angular inserts a single instead of rebuilding the list. Track on something stable and unique — a database id, not an array index and not a display string. Class and style bindings, not A common carry-over from older code: Use the native bindings instead. They need no import, they are faster, and they are what the current guide asks for: You can also bind a whole object with or when the set of keys is dynamic. Spread syntax in templates Angular 22 added spread and rest syntax to template expressions — in object literals, array literals, and function calls. It is small, but it removes a category of helper methods: Before this, both of those needed a in the class or a method call in the template. For simple assembly like the above, the template version is now fine. The golden rule: calculations belong in TypeScript Templates accept JavaScript-like expressions, which makes it tempting to do arithmetic in HTML. Resist it. Bad — business rules hidden in markup: Good — compute in the class, display in the template: Note the . Angular's style guide asks you to mark members that only the template reads as — it keeps them out of the public surface of the class while staying reachable from the template. "But I thought calling a method in a template was fine now that we have OnPush" This is a fair assumption. is the default in Angular 22, so a component is only checked when something it depends on changes. Surely that means a method call in a template is cheap? It is cheaper. It is not free, and it is not cached. When Angular does check a component — because a signal changed, or the user typed in that component's own template — it re-evaluates every expression in the template, including every method call, once per binding per check. Type one character into a filter box in that same component and runs 40 times. Type ten characters and it runs 400 times. Worse, if it returns an object literal, every call produces a new reference , so all 40 children see a "changed" input and re-render — you have defeated the default you were relying on. A fixes both halves. It caches, and it hands back the same reference until its inputs actually change: The belief is reasonable because really did remove the worst version of this problem — the one where every keystroke anywhere in the app re-ran your method. It did not make template method calls cached. 40 centre cards, 10 keystrokes in a filter box Method in template --- --- --- executions 400 1 (recomputes only if changes) Child components re-rendered 400 0 Object references created 400 40, once Recap Templates are declarative. Describe the UI for a state; never step through DOM changes yourself. Three bindings do the work. for text, for properties and inputs, for events. Use native control flow. , with a stable , , and . Use and bindings. and are no longer recommended. Angular 22 allows spread and rest in template expressions — useful for small object and array assembly. Calculate in TypeScript. caches and keeps references stable; a method in a template does neither. Mark template-only members . Next: what to do when you need behaviour on an element without inventing a new tag.