Reputation: 529
During the upgrade process of Font Awesome 5 from 4.7.0, I noticed that any class bindings I gave to an <i>
tag would not function as it did before.
Imagine the following element with a class binding:
<i class.bind="iconClass"></i>
And imagine the initial value of the iconClass
being 'fas fa-cog'
. When changing the value of iconClass
to 'fas fa-ship'
, the icon won't update to the newly set icon classes. It will remain a cog icon.
I believe this happens because Font Awesome 5 replaces the <i>
tags with <svg>
tags and doesn't copy over the class binding properly and thus not trigger an icon change.
In the following example, the bound classes are changed after two seconds to illustrate the problem, please see this GistRun for an example of the issue. See app.html
and app.js
for the implementation. It also contains a dirty workaround.
How can/should this behaviour be implemented?
Upvotes: 5
Views: 2625
Reputation: 529
Inspired by the answer of @huocp utilising innerhtml
.
Using a custom component to solve this problem does indeed work. However, as I will only be having one icon with a class binding in my project, I have found a simpler way of doing this:
<i innerhtml="<i class='${iconClass}'></i>"></i>
A change of the iconClass
value will generate a new <i>
child (while replacing the old <svg>
element) within the parent, after which Font Awesome 5 will convert this <i>
child into an <svg>
.
Any elements can be used as parent and child elements of course, I just think <i>
looks short and clean, it will nest the <svg>
generated by Font Awesome 5 within the <i>
.
Upvotes: 3
Reputation:
See working gistrun here: https://gist.run/?id=55559f3bd606aa854502f3ddbbcad480
Use this custom component like this.
<fa-svg icon-class.bind="iconClass"></fa-svg>
fa-svg.js
import {inject, inlineView, bindable} from 'aurelia-framework';
@inject(Element)
@inlineView("<template></template>")
export class FaSvg {
@bindable iconClass;
constructor(element) {
this.element = element;
}
iconClassChanged(newIcon) {
if (!this.live) return;
this._rebuild(newIcon);
}
attached() {
this.live = true;
this._rebuild(this.iconClass);
}
detached() {
this.live = false;
}
_rebuild(iconClass) {
this.element.innerHTML = iconClass ? `<i class="${iconClass}"></i>` : '';
}
}
Upvotes: 2
Reputation:
I had exactly same issue before.
As you said, you were using "svg with js" (the fa5 recommended way). It does fight Aurelia since the svg version use JavaScript to replace DOM element, the binding of Aurelia getting destroyed along with old DOM element.
Switch to "web font with css" which fa5 supported perfectly. It will obey your command as fa4.
Upvotes: 1