Introduces a new Link primitive to pass around self-contained references to
routes, like URLs, but with state (isActive, ...) and methods (transitionTo,
...). Also brings along an accompanying template helper and component for easy
usage in templates.
ember-linkdoes to routing whatember-concurrencydid to asynchrony!
— /r/whatjawsdid
ember install ember-link
👉 This is an Ember Octane addon. For a version that is compatible with older versions of Ember check out the
0.xseries.
👉 You are viewing the docs for an improved & refactored release (
^1.1.0), that is 100 % backwards compatible to the1.0.0version you're used to. There's no reason not to upgrade. ✨
The {{link}} helper returns a UILink instance.
When passing a single model, you can use model instead of models:
You can also mix and match the parameter styles, however you like.
Instead of the positional & named link parameters described above, you can also
create a Link instance from a serialized URL.
fromURL is mutually exclusive with the other link parameters: route, model
& models, query
In addition to the parameters shown above, the {{link}} helper also accepts a
preventDefault default parameter. It defaults to true and intelligently
prevents hard browser transitions when clicking <a> elements.
See @preventDefault and UILink.
Instead of using the {{#let}} helper, you can use the
<Link> component to achieve the same scoping effect, with
subjectively nicer syntax.
Even better yet, make Link / UILink a first-class
primitive in your app architecture! Instead of manually wiring up
Link#url and Link#transitionTo() every time, rather
create your own ready-to-use, style-guide-compliant link and button components
that accept @link as an argument instead of @href and @onClick.
This is akin to the popular async task button component concept.
Similar to the the {{link}} helper, the <Link> component
yields a UILink instance.
Required.
The target route name.
Example
{{link-to}} equivalent
Optional. Mutually exclusive with @model.
An array of models / dynamic segments.
Example
{{link-to}} equivalent
Optional. Mutually exclusive with @models.
Shorthand for providing a single model / dynamic segment. The following two invocations are equivalent:
Optional.
Query Params object.
Example
{{link-to}} equivalent
Optional. Mutually exclusive with @route, @model /
@models, @query.
Example
Optional. Default: true
If enabled, the transitionTo and
replaceWith actions will try to call
event.preventDefault() on the first argument, if it is an
event. This is an anti-foot-gun to make <Link> just work™️ with <a> and
<button>, which would otherwise trigger a native browser navigation / form
submission.
The <Link> component yields a UILink instance.
string
The URL for this link that you can pass to an <a> tag as the href attribute.
boolean
Whether this route is currently active, including potentially supplied models and query params.
In the following example, only one link will be is-active at any time.
boolean
Whether this route is currently active, including potentially supplied models, but ignoring query params.
In the following example, the first two links will be is-active simultaneously.
boolean
Whether this route is currently active, but ignoring models and query params.
In the following example, both links will be is-active simultaneously.
(event?: Event) => Transition
Transition into the target route.
If @preventDefault is enabled, also calls event.preventDefault().
(event?: Event) => Transition
Transition into the target route while replacing the current URL, if possible.
If @preventDefault is enabled, also calls event.preventDefault().
A Link is a self-contained reference to a concrete route, including models and
query params. It's basically like a
<LinkTo> / {{link-to}} component you can pass around.
You can create a Link via the LinkManager service.
UILink extends Link with some anti-foot-guns and conveniences. It
can also be created via the LinkManager service, but also via
the {{link}} helper and <Link> component.
Type: boolean
Whether this route is currently active, including potentially supplied models and query params.
Type: boolean
Whether this route is currently active, including potentially supplied models, but ignoring query params.
Type: boolean
Whether this route is currently active, but ignoring models and query params.
Type: string
The URL for this link that you can pass to an <a> tag as the href attribute.
Type: string
The target route name of this link.
Type: RouteModel[]
The route models passed in this link.
Type: Record<string, unknown> | undefined
The query params for this link, if specified.
Returns: Transition
Transition into the target route.
Returns: Transition
Transition into the target route while replacing the current URL, if possible.
UILink extends Link with anti-foot-guns and conveniences. This
class is meant to be used in templates, primarily through <a> & <button>
elements.
It wraps transitionTo() and replaceWith() to optionally accept an event
argument. It will intelligently
- call
event.preventDefault()to prevent hard page reloads - open the page in a new tab, when
Cmd/Ctrlclicking
It can be created via the LinkManager service, but also via
the {{link}} helper and <Link> component.
The LinkManager service is used by the {{link}} helper and
<Link> component to create UILink instances.
You can also use this service directly to programmatically create link references.
Returns: Link
interface LinkParams {
/**
* The target route name.
*/
route: string;
/**
* Optional array of models / dynamic segments.
*/
models?: RouteModel[];
/**
* Optional query params object.
*/
query?: QueryParams;
}Returns: UILink
interface UILinkParams {
/**
* Whether or not to call `event.preventDefault()`, if the first parameter to
* the `transitionTo` or `replaceWith` action is an `Event`. This is useful to
* prevent links from accidentally triggering real browser navigation or
* buttons from submitting a form.
*
* Defaults to `true`.
*/
preventDefault?: boolean;
}Returns: LinkParams
Use this method to derive LinkParams from a serialized, recognizable URL, that
you can then pass into createLink / createUILink.
In acceptance / application tests (setupApplicationTest(hooks))
your app boots with a fully-fledged router, so ember-link just works normally.
In integration / render tests (setupRenderingTest(hooks)) the
router is not initialized, so ember-link can't operate normally. To still
support using {{link}} & friends in render tests, you can use the
setupLink(hooks) test helper.
import { click, render } from '@ember/test-helpers';
import { setupRenderingTest } from 'ember-qunit';
import { module, test } from 'qunit';
import { setupLink, linkFor, TestLink } from 'ember-link/test-support';
import hbs from 'htmlbars-inline-precompile';
module('`setupLink` example', function (hooks) {
setupRenderingTest(hooks);
setupLink(hooks);
test('`<Link>` component works in render tests', async function (assert) {
await render(hbs`
<Link @route="some.route" as |l|>
<a
href={{l.url}}
class={{if l.isActive "is-active"}}
{{on "click" l.transitionTo}}
>
Click me
</a>
</Link>
`);
const link = linkFor('some.route');
link.onTransitionTo = assert.step('link clicked');
await click('a');
assert.verifySteps(['link clicked']);
});
});ember-engine-router-service: Allows you to useember-linkinside enginesember-router-helpers- RFC 391 "Router Helpers"
- RFC 339 "Router link component and routing helpers"
- RFC 459 "Angle Bracket Invocations For Built-in Components"