QuizListComponent

This component plays a key role in our Angular app and desperately needs a better layout; we'll change a lot of things here to make it more enjoyable.

Open the quiz-list.component.html template file and perform the following changes (new/updated lines are highlighted):

<div class="panel panel-primary {{class}}">
<div class="panel-heading">
<span class="glyphicon"></span>
<h4>{{title}}</h4>
</div>
<div class="panel-body">
<ul class="list-group">
<li class="list-group-item"
*ngFor="let quiz of quizzes"
[class.selected]="quiz === selectedQuiz"
(click)="onSelect(quiz)">
<img src="https://lorempixel.com/50/50/?random=
{{quiz.Id}}"

alt="{{quiz.Title}}" class="img-circle" />
<span>{{quiz.Title}}</span>
</li>
</ul>
</div>
</div>

As we can see, the underlying logic didn't change; we still have a *ngFor cycle that iterates through the quizzes array, pulls out a quiz object ent, and uses its properties to build an HTML unordered list. We just wrapped it with a Bootstrap panel to ensure that it will have a properly-styled container; if we take a closer look at line 1, we can see how we also added the {{class}} interpolation directive to ensure that the container panel will have the same class attribute value given to that QuizListComponent instance by its parent component, as previously seen in the HomeComponent template file.

Other than that, we also added a random image using lorempixel.com, a free-of-charge web service that can be used to fetch placeholders images for sample layouts.

Note how we're adding a random GET parameter to each HTTP request to the lorempixel.com service with the {{quiz.Id}} as value; we did that to prevent the web browser from caching these images, which is a common scenario when requesting the same URL multiple times from the same page.

Also, here's the quiz-list.component.less style sheet file:

.panel {
margin-bottom: 12px;

.panel-heading {
color: #fefefe;

.glyphicon {
float: right;
font-size: 41px;
color: #d6d6d6;
}
}

.panel-body {
padding: 0;

.list-group {
margin: 0;

.list-group-item {
padding: 6px;
overflow: auto;
cursor: pointer;

&amp;:hover {
background-color: #dae9f5;

&amp;:before {
display: inline-block;
font-family: 'Glyphicons Halflings';
content: "e013";
float: right;
font-size: 30px;
margin: 4px 5px 0 0;
color: #60a777;
}
}

img {
display: block;
float: left;
width: 50px;
height: 50px;
background-color: #ffffff;
border: 1px solid #707d8c;
padding: 2px;
margin: 0 6px 0 0;
}
}
}
}

&amp;.latest {
border-color: #384a5d;

.panel-heading {
background-color: #384a5d;

.glyphicon:before {
content: "e162";
}
}
}

&amp;.byTitle {
border-color: #4b657f;

.panel-heading {
background-color: #4b657f;

.glyphicon:before {
content: "e151";
}
}
}

&amp;.random {
border-color: #617992;

.panel-heading {
background-color: #617992;

.glyphicon:before {
content: "e104";
}
}
}
}

These style sheet rules are quite complex, so it might be worthwile spending a couple of words on them; again, we used the LESS nested selectors feature, which allows us to encapsulate children selectors within their parent set of rules. We defined a single "main" .panel selector, which basically contains the following things:

  • A very limited set of rules that will be applied to the selector itself (the "margin-bottom" single line)
  • A .panel-heading child selector, containing the generic configuration for the panel heading DIV element; these rules will be applied to any QuizListComponent instance's template, regardless of the class attribute value
  • A .panel-body child selector, containing the generic configuration for the panel body DIV element; again, these rules will be applied to all QuizListComponent instances
  • A set of selectors relative by itself--&amp;.latest , &amp;.byTitle, and &amp;.random; these rules will be applied only to the QuizListComponent instance with that specific class , thus ensuring a different styling for each different class

The last bullet might be quite difficult to get; to better understand it, let's perform a quick recap to understand how the &amp; ampersand selector actually works. If we recall correctly, it represents the current selector's parent, meaning that the &amp;.latest , &amp;.byTitle, and &amp;.random selectors--along with their "children" --will be CSS-compiled to .panel.latest, .panel.byTitle, and .panel.random , and so on, right?

That's right, we can easily confirm that by looking at the autogenerated quiz-list.component.css file:

[...]

.panel.latest {
border-color: #384a5d;
}
.panel.latest .panel-heading {
background-color: #384a5d;
}
.panel.latest .panel-heading .glyphicon:before {
content: "e162";
}
.panel.byTitle {
border-color: #4b657f;
}

[...]

.panel.random {
border-color: #617992;
}

[...]

By looking at that, we can acknowledge that only one of these selectors will be applied to each single QuizListComponent instance, depending on the class specified upon their initialization in the HomeComponent template file:

[...]
<quiz-list class="latest"></quiz-list>
[...]
<quiz-list class="byTitle"></quiz-list>
[...]
<quiz-list class="random"></quiz-list>
[...]

This is certain since we explicitly put that same class in the quiz-list.component.html template file's container <div> element using the {{class}} interpolation directive:

<div class="panel panel-primary {{class}}">

[...]

This concludes our journey through the QuizListComponent files, at least for now.

We would like to talk a bit more about the other styling rules we used within the LESS file, but we can't do that without compromising on the book length; the reader can easily understand their purpose by tracking their respective selectors using the browser's DOM inspector.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.206.225