So you're creating a link with the Angular UI Router. You're passing more than a few parameters and it's getting kinda big. Something like this:
<a class="contains-icon"
ui-sref="Entity.Edit({ entityId: (vm.selectedEntityId ? vm.selectedEntityId: null), initialData: vm.initialData })">
<i class="fa fa-pencil"></i>Edit
</a>
See? It's too long to fit on the screen without wrapping. It's clearly mad and bad.
Generally I try to keep the logic in a view to a minimum. It makes the view harder to read, it makes behaviour of the app harder to reason about. Also, it's not testable and (if you're using some kind of static typing like TypeScript) it is entirely out of the realms that a compiler can catch. So what to do? Move the URL generation to the controller. That's what I decided to do after I had a typo in my view which I didn't catch until post-commit.
ui-sref
in the Controller
Actually, that's not exactly what you want to do. If you look at the Angular UI Router docs you will see that ui-sref
is:
...a directive that binds a link (<a>
tag) to a state. If the state has an associated URL, the directive will automatically generate & update the href attribute via the$state.href()
method.
So what we actually want to do is use the $state.href()
method in our controller. To take our example above we'll create another method on our controller called getEditUrl
export class EntityController {
$state: angular.ui.IStateService;
static $inject = ["$state"];
constructor($state: angular.ui.IStateService) {
this.$state = $state;
}
//... Other stuff
getEditUrl() {
return this.$state.href("Entity.Edit", {
selectedEntityId: this.selectedEntityId ? this.selectedEntityId: null,
initialData: this.initialData
});
}
}
You can see I'm using TypeScript here; but feel free to strip out the type annotations and go with raw ES6 classes; that'll still give you testability if not static typing.
Now we've added the getEditUrl
method we just need to reference it in our view:
<a class="contains-icon" ng-href="{{vm.getEditUrl()}}"><i class="fa fa-pencil"></i>Edit</a>
Note we've ditched usage of the ui-sref
directive and gone with Angular's native ng-href
. Within that directive we execute our getEditUrl
as an expression which gives us our route. As a bonus, our view is much less cluttered and comprehensible as a result. How lovely.