Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 48fb6ad

Browse files
authored
docs(template-syntax): ngClass and ngStyle binding examples not horrible (#3076)
closes #3072, whose criticism prompted these changes.
1 parent aff39d2 commit 48fb6ad

File tree

4 files changed

+65
-84
lines changed

4 files changed

+65
-84
lines changed

public/docs/_examples/template-syntax/ts/app/app.component.html

+28-26
Original file line numberDiff line numberDiff line change
@@ -409,15 +409,23 @@ <h3>Result: {{currentHero.firstName}}</h3>
409409
<!-- NgClass binding -->
410410
<hr><h2 id="ngClass">NgClass Binding</h2>
411411

412-
<p>setClasses returns {{setClasses() | json}}</p>
412+
<p>currentClasses returns {{currentClasses | json}}</p>
413413
<!-- #docregion NgClass-1 -->
414-
<div [ngClass]="setClasses()">This div is saveable and special</div>
414+
<div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>
415415
<!-- #enddocregion NgClass-1 -->
416-
<div [ngClass]="setClasses()" #classDiv>
417-
After setClasses(), the classes are "{{classDiv.className}}"
418-
</div>
419416

420417
<!-- not used in chapter -->
418+
<br>
419+
<label>saveable <input type="checkbox" [(ngModel)]="canSave"></label> |
420+
<label>modified: <input type="checkbox" [value]="!isUnchanged" (change)="isUnchanged=!isUnchanged"></label> |
421+
<label>special: <input type="checkbox" [(ngModel)]="isSpecial"></label>
422+
<button (click)="setCurrentClasses()">Refresh currentClasses</button>
423+
<br><br>
424+
<div [ngClass]="currentClasses">
425+
This div should be {{ canSave ? "": "not"}} saveable,
426+
{{ isUnchanged ? "unchanged" : "modified" }} and,
427+
{{ isSpecial ? "": "not"}} special after clicking "refresh".</div>
428+
<br><br>
421429

422430
<div [ngClass]="isSpecial ? 'special' : ''">This div is special</div>
423431

@@ -429,38 +437,32 @@ <h3>Result: {{currentHero.firstName}}</h3>
429437
<!-- NgStyle binding -->
430438
<hr><h2 id="ngStyle">NgStyle Binding</h2>
431439

432-
<!-- #docregion NgStyle -->
433-
<div>
434-
<p [ngStyle]="setStyle()" #styleP>Change style of this text!</p>
435-
436-
<label>Italic: <input type="checkbox" [(ngModel)]="isItalic"></label> |
437-
<label>Bold: <input type="checkbox" [(ngModel)]="isBold"></label> |
438-
<label>Size: <input type="text" [(ngModel)]="fontSize"></label>
439-
440-
<p>Style set to: <code>'{{styleP.style.cssText}}'</code></p>
441-
</div>
442-
<!-- #enddocregion NgStyle -->
443-
444440
<!-- #docregion NgStyle-1 -->
445441
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >
446442
This div is x-large.
447443
</div>
448444
<!-- #enddocregion NgStyle-1 -->
449445

450-
<h3>Use setStyles() - CSS property names</h3>
451-
<p>setStyles returns {{setStyles() | json}}</p>
446+
<h3>[ngStyle] binding to `currentStyles` - CSS property names</h3>
447+
<p>currentStyles returns {{currentStyles | json}}</p>
452448
<!-- #docregion NgStyle-2 -->
453-
<div [ngStyle]="setStyles()">
454-
This div is italic, normal weight, and extra large (24px).
449+
<div [ngStyle]="currentStyles">
450+
This div is initially italic, normal weight, and extra large (24px).
455451
</div>
456452
<!-- #enddocregion NgStyle-2 -->
457-
<p>After setStyles(), the DOM confirms that the styles are
458-
<span [ngStyle]="setStyles()" #styleDiv>
459-
{{getStyles(styleDiv)}}
460-
</span>.
461-
</p>
462453

463454
<!-- not used in chapter -->
455+
<br>
456+
<label>italic: <input type="checkbox" [(ngModel)]="canSave"></label> |
457+
<label>normal: <input type="checkbox" [(ngModel)]="isUnchanged"></label> |
458+
<label>xlarge: <input type="checkbox" [(ngModel)]="isSpecial"></label>
459+
<button (click)="setCurrentStyles()">Refresh currentStyles</button>
460+
<br><br>
461+
<div [ngStyle]="currentStyles">
462+
This div should be {{ canSave ? "italic": "plain"}},
463+
{{ isUnchanged ? "normal weight" : "bold" }} and,
464+
{{ isSpecial ? "extra large": "normal size"}} after clicking "refresh".</div>
465+
<br>
464466

465467
<a class="to-toc" href="#toc">top</a>
466468

public/docs/_examples/template-syntax/ts/app/app.component.ts

+17-49
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export class AppComponent implements AfterViewInit, OnInit {
2525

2626
ngOnInit() {
2727
this.refreshHeroes();
28+
this.setCurrentClasses();
29+
this.setCurrentStyles();
2830
}
2931

3032
ngAfterViewInit() {
@@ -56,14 +58,10 @@ export class AppComponent implements AfterViewInit, OnInit {
5658

5759
title = 'Template Syntax';
5860

59-
// DevMode memoization fields
60-
private priorClasses: {};
61-
private _priorStyles: {};
62-
6361
getStyles(el: Element) {
6462
let styles = window.getComputedStyle(el);
6563
let showStyles = {};
66-
for (let p in this.setStyles()) {
64+
for (let p in this.currentStyles) { // only interested in these styles
6765
showStyles[p] = styles[p];
6866
}
6967
return JSON.stringify(showStyles);
@@ -141,58 +139,29 @@ export class AppComponent implements AfterViewInit, OnInit {
141139
}
142140

143141
// #docregion setClasses
144-
setClasses() {
145-
let classes = {
146-
saveable: this.canSave, // true
147-
modified: !this.isUnchanged, // false
148-
special: this.isSpecial, // true
142+
currentClasses: {};
143+
setCurrentClasses() {
144+
// CSS classes: added/removed per current state of component properties
145+
this.currentClasses = {
146+
saveable: this.canSave,
147+
modified: !this.isUnchanged,
148+
special: this.isSpecial
149149
};
150-
// #enddocregion setClasses
151-
// compensate for DevMode (sigh)
152-
if (JSON.stringify(classes) === JSON.stringify(this.priorClasses)) {
153-
return this.priorClasses;
154-
}
155-
this.priorClasses = classes;
156-
// #docregion setClasses
157-
return classes;
158150
}
159151
// #enddocregion setClasses
160152

161-
162153
// #docregion setStyles
163-
setStyles() {
164-
let styles = {
165-
// CSS property names
166-
'font-style': this.canSave ? 'italic' : 'normal', // italic
167-
'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal
168-
'font-size': this.isSpecial ? '24px' : '8px', // 24px
154+
currentStyles: {};
155+
setCurrentStyles() {
156+
this.currentStyles = {
157+
// CSS styles: set per current state of component properties
158+
'font-style': this.canSave ? 'italic' : 'normal',
159+
'font-weight': !this.isUnchanged ? 'bold' : 'normal',
160+
'font-size': this.isSpecial ? '24px' : '12px'
169161
};
170-
// #enddocregion setStyles
171-
// compensate for DevMode (sigh)
172-
if (JSON.stringify(styles) === JSON.stringify(this._priorStyles)) {
173-
return this._priorStyles;
174-
}
175-
this._priorStyles = styles;
176-
// #docregion setStyles
177-
return styles;
178162
}
179163
// #enddocregion setStyles
180164

181-
// #docregion NgStyle
182-
isItalic = false;
183-
isBold = false;
184-
fontSize: string = 'large';
185-
fontSizePx: number | string = 14;
186-
187-
setStyle() {
188-
return {
189-
'font-style': this.isItalic ? 'italic' : 'normal',
190-
'font-weight': this.isBold ? 'bold' : 'normal',
191-
'font-size': this.fontSize
192-
};
193-
}
194-
// #enddocregion NgStyle
195-
196165
toeChoice = '';
197166
toeChooser(picker: HTMLFieldSetElement) {
198167
let choices = picker.children;
@@ -202,7 +171,6 @@ export class AppComponent implements AfterViewInit, OnInit {
202171
}
203172
}
204173

205-
206174
// #docregion trackByHeroes
207175
trackByHeroes(index: number, hero: Hero) { return hero.id; }
208176
// #enddocregion trackByHeroes

public/docs/_examples/template-syntax/ts/template-syntax.css

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ img {height: 100px;}
66
.parent-div {margin-top: 1em; font-weight: bold}
77
.special {font-weight:bold; font-size: x-large}
88
.bad {color: red;}
9-
.curly {font-family: "Brush Script MT"}
9+
.saveable {color: limegreen;}
10+
.curly, .modified {font-family: "Brush Script MT"}
1011
.toe {margin-left: 1em; font-style: italic;}
1112
little-hero {color:blue; font-size: smaller; background-color: Turquoise }
12-
.to-toc {margin-top: 10px; display: block}
13+
.to-toc {margin-top: 10px; display: block}

public/docs/ts/latest/guide/template-syntax.jade

+17-7
Original file line numberDiff line numberDiff line change
@@ -997,15 +997,22 @@ figure.image-display
997997
The `NgClass` directive may be the better choice
998998
when we want to add or remove *many* CSS classes at the same time.
999999

1000-
A good way to apply `NgClass` is by binding it to a key:value control !{__objectAsMap}. Each key of the object is a CSS class name; its value is `true` if the class should be added, `false` if it should be removed.
1000+
A good way to apply `NgClass` is by binding it to a key:value control !{__objectAsMap}.
1001+
Each key of the object is a CSS class name; its value is `true` if the class should be added,
1002+
`false` if it should be removed.
10011003

10021004
:marked
1003-
Consider a component method such as `setClasses` that manages the state of three CSS classes:
1005+
Consider a
1006+
`setCurrentClasses` component method that sets a component property, `currentClasses`
1007+
with an object that adds or removes three classes based on the
1008+
`true`/`false` state of three other component propertes:
10041009
+makeExample('template-syntax/ts/app/app.component.ts', 'setClasses')(format=".")
10051010
:marked
1006-
Now we can add an `NgClass` property binding that calls `setClasses`
1007-
and sets the element's classes accordingly:
1011+
Adding an `NgClass` property binding to `currentClasses` sets the element's classes accordingly:
10081012
+makeExample('template-syntax/ts/app/app.component.html', 'NgClass-1')(format=".")
1013+
.l-sub-section
1014+
:marked
1015+
It's up to you to call `setCurrentClassess()`, both initially and when the dependent properties change.
10091016

10101017
<a id="ngStyle"></a>
10111018
.l-main-section
@@ -1023,12 +1030,15 @@ figure.image-display
10231030
We apply `NgStyle` by binding it to a key:value control !{__objectAsMap}.
10241031
Each key of the object is a style name; its value is whatever is appropriate for that style.
10251032

1026-
Consider a component method such as `setStyles` that returns an object defining three styles:
1033+
Consider a `setCurrentStyles` component method that sets a component property, `currentStyles`
1034+
with an object that defines three styles, based on the state of three other component propertes:
10271035
+makeExample('template-syntax/ts/app/app.component.ts', 'setStyles')(format=".")
10281036
:marked
1029-
Now we just add an `NgStyle` property binding that calls `setStyles`
1030-
and sets the element's styles accordingly:
1037+
Adding an `NgStyle` property binding to `currentStyles` sets the element's styles accordingly:
10311038
+makeExample('template-syntax/ts/app/app.component.html', 'NgStyle-2')(format=".")
1039+
.l-sub-section
1040+
:marked
1041+
It's up to you to call `setCurrentStyles()`, both initially and when the dependent properties change.
10321042

10331043
<a id="ngIf"></a>
10341044
.l-main-section

0 commit comments

Comments
 (0)