# Reusing an Existing View Model

**URL:** <https://discourse.aurelia.io/t/reusing-an-existing-view-model/3154>\
**Category:** Framework Knowledge\
**Created:** [January 13, 2020, 5:21pm UTC](https://discourse.aurelia.io/t/reusing-an-existing-view-model/3154 "2020-01-13T17:21:50Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alfhir](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/alfhir/32/1510_2.png) [@Alfhir](https://discourse.aurelia.io/u/Alfhir)\
**Post date:** [January 13, 2020, 5:21pm UTC](https://discourse.aurelia.io/t/reusing-an-existing-view-model/3154/1 "2020-01-13T17:21:50Z")

</div>

Hi,

could someone please elaborate on this?

I find “Available return values are `replace` and `invoke-lifecycle` . Remember, “lifecycle” refers to the navigation lifecycle.” in the [cheatsheet](https://aurelia.io/docs/fundamentals/cheat-sheet#routing) rather distracting.

What will actually tell the router to re-use a view-model?

Will create a PR for the docs when clarified.

Thx

---

<div class="post-metadata">

**Author:** ![huochunpeng](https://avatars.discourse-cdn.com/v4/letter/h/49beb7/32.png) [@huochunpeng](https://discourse.aurelia.io/u/huochunpeng)\
**Post date:** [January 13, 2020, 9:23pm UTC](https://discourse.aurelia.io/t/reusing-an-existing-view-model/3154/2 "2020-01-13T21:23:39Z")

</div>

This only affects routes using exactly same view-model, like the example in doc:

```auto
{ route: 'product/a', moduleId: 'product', nav: true },
{ route: 'product/b', moduleId: 'product', nav: true },

```

When you navigate the app from page `product/a` to `product/b`, ~~for efficiency, aurelia will reuse the instance (`new Product(...)`) created by the old page to render the new page. That means the default strategy is `invoke-lifecycle`~~.

**Update** : the above is wrong, the default strategy is `no-change`, means aurelia does nothing, this is definitely not what you expected. `invoke-lifecycle` however means aurelia will reuse the instance (`new Product(...)`) created by the old page to render the new page.

`invoke-lifecycle` means aurelia **only issues `canDeactivate, deactivate, canActivate, activate` callbacks on the same instance (`new Product(...)`) to switch from one route to another**. This is efficient, but might surprise developers, because the instance is not in a clean state, you really need to be careful to design the logic to tolerant dirty state during route transition.

I would much like `replace` to be the default strategy. It’s less performant, but more intuitive to developers.

For routes transition across different view-models, this strategy value is irrelevant, because aurelia has to create new instance of new view-model, there is nothing can be reused through `invoke-lifecycle`.

---

<div class="post-metadata">

**Author:** ![huochunpeng](https://avatars.discourse-cdn.com/v4/letter/h/49beb7/32.png) [@huochunpeng](https://discourse.aurelia.io/u/huochunpeng)\
**Post date:** [January 13, 2020, 9:35pm UTC](https://discourse.aurelia.io/t/reusing-an-existing-view-model/3154/3 "2020-01-13T21:35:49Z")

</div>

To be clear

```auto
export const determineActivationStrategy = (
  currentNavInstruction: NavigationInstruction,
  prevViewPortInstruction: ViewPortInstruction,
  newViewPortConfig: RouteConfig | ViewPortInstruction,
  // indicates whether there is difference between old and new url params
  hasNewParams: boolean,
  forceLifecycleMinimum?: boolean
): ActivationStrategyType => {

  let newInstructionConfig = currentNavInstruction.config;
  let prevViewPortViewModel = prevViewPortInstruction.component.viewModel;
  let viewPortPlanStrategy: ActivationStrategyType;

  if (prevViewPortInstruction.moduleId !== newViewPortConfig.moduleId) {
// different view-model, use "replace".
    viewPortPlanStrategy = InternalActivationStrategy.Replace;
  } else if ('determineActivationStrategy' in prevViewPortViewModel) {
// when you defined determineActivationStrategy() in view-model
    viewPortPlanStrategy = prevViewPortViewModel.determineActivationStrategy(...currentNavInstruction.lifecycleArgs);
  } else if (newInstructionConfig.activationStrategy) {
// when you define activationStrategy in route config like
// { route: ..., moduleId: ..., activationStrategy: 'replace'}
    viewPortPlanStrategy = newInstructionConfig.activationStrategy;
  } else if (hasNewParams || forceLifecycleMinimum) {
// when you navigate from product/a to product/b for a route defined
// with params like product/:id
// use invoke-lifecycle
    viewPortPlanStrategy = InternalActivationStrategy.InvokeLifecycle;
  } else {
// default to no-change
    viewPortPlanStrategy = InternalActivationStrategy.NoChange;
  }
  return viewPortPlanStrategy;
};

```
