Reputation: 101
I am just starting with Angular and have a problem with *ngIf
When the app starts, *ngIf="item.done"
correctly displays (or not displays) the element based on whether the ToDo item
is done
. However, when I click on the element, the done
state changes (I am console.logging it), but the element doesn't disappear, whatever the state. Instead, when the state goes back to done
, it creates the same element again.
The onTick()
function that changes the item.done
state
item.done = false
Hidden Screenshotitem.done = true
Shownitem.done = false
Shownitem.done = true
Shown TWICE Screenshot // MOCK DATA
import { Item } from './item';
export const ITEMS: Item[] = [
{id: 1, title: 'Buy Milk', done: false},
{id: 2, title: 'Do Math', done: true},
{id: 3, title: 'Cook food', done: false}
]
// THE COMPONENT TypeScript
import { Component, OnInit } from '@angular/core';
import { ITEMS } from './mock-items';
import { Item } from './item';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
items: Item[] = [];
constructor() {
this.items = ITEMS
}
ngOnInit() {
}
onTick(item) {
console.log('Item was: ', item.done)
item.done = !item.done
console.log('Item became: ', item.done)
}
}
<!-- THE COMPONENT HTML -->
<div class="list">
<div class="list--header">
<h1>List</h1>
</div>
<div class="list--content">
<ul class="list--items">
<li *ngFor="let item of items">
<div class="checkbox" (click)="onTick(item)">
<input type="checkbox" style="display: none">
<i *ngIf="item.done" class="tick fas fa-check"></i>
</div>
{{item.title}}
</li>
</ul>
</div>
<div class="list--footer">
</div>
</div>
Upvotes: 7
Views: 6986
Reputation: 8879
Adding to the list of suggested answers.
You can set the FontAwesomeConfig
property autoReplaceSvg
to nest
, which will automatically nest the SVG inside the <i>
element instead, and thus not mess up the HTML.
<script>
// Add in your index.html or similar
FontAwesomeConfig = { autoReplaceSvg: 'nest' }
</script>
And use it like normal
<i class="my-icon fas fa-coffee" data-fa-mask="fas fa-circle"></i>
and you'll get the following result
<i class="my-icon" data-fa-mask="fas fa-circle" data-fa-processed="">
<svg class="svg-inline--fa fa-coffee fa-w-16" data-fa-mask="fas fa-circle" aria-hidden="true" data-fa-processed="" data-prefix="fas" data-icon="coffee" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">...</svg>
</i>
Check out the documentation for further reference.
Upvotes: 1
Reputation: 101
EDIT
The problem happens when Font Awesome's SVG, instead of appearing as a child of the
<i *ngIf="item.done" class="tick fas fa-check"></i>
, replaces the element, and so the*ngIf
attribute disappears. Looks like we shouldn't ever use Angular attributes on an element with Font Awesome classes (target the parent element, instead).
How it Used to Be (Doesn't work)
<i *ngIf="item.done" class="tick fas fa-check"></i>
Solution
<div *ngIf="item.done">
<i class="tick fas fa-check"></i>
</div>
Upvotes: 3
Reputation: 771
Try wrapping the icon in a DIV... Also it is important to note that ngIf isn't intended to "hide" elements. It will in fact add and remove them from the DOM. If your intent is to hide/show, you should take a look at ngHide.
Hope this helps.
Upvotes: 2