简体   繁体   中英

Angular2 router.navigate reloads app

I have the following routes defined in my app ...

app.components.ts
@RouteConfig([
  {path:'/employees/...', name:'Employees', component:EmployeeComponent},
  ...

employee.component.ts
@RouteConfig([
  {path:'/', name:'EmployeeList', component:EmployeeListComponent, useAsDefault: true},
  {path:'/:id', name:'EmployeeDetail', component:EmployeeDetailComponent}
])

When I route from the EmployeeDetailComponent template ...

<button class="btn btn-default" [routerLink]="['EmployeeList']">Close</button>

the app routes to the employee listing page as expected.

However, when I route using router.navigate ...

// template
<button class="btn btn-default" (click)="save()">Save</button>

// EmployeeDetailComponent
saveEmployee() {
  this._employeeServer.updateEmployee(this.employee);
  this._router.navigate(['EmployeeList']);
}

the app routes the the employee listing (as expected) and then, a few moments later, the app reloads entirely (not as expected).

Any idea why router.navigate is behaving differently than routerLink? What am I missing?

<button> within <form> may be trying to submit. Try adding <button type="button"> to prevent the from submitting when clicking the button.

You could use this directive:

@Directive({
  selector: `click-stop-propagation`
  events: 'stopClick($event)'
})
class ClickStopPropagation {
  stopClick(event:Event) {
    event.preventDefault();
    event.stopPropagation();
  }
}

and apply it this way:

<button class="btn btn-default"
    (click)="save()" click-stop-propagation>Save</button>

Another solution would be to pass the event to the save method:

<button class="btn btn-default"
    (click)="save($event)" click-stop-propagation>Save</button>

and use it to stop the event propagation:

save(event) {
  this._employeeServer.updateEmployee(this.employee);
  this._router.navigate(['EmployeeList']);
  event.preventDefault();
  event.stopPropagation();
}

While Thierry's answer with cancelling the event propagation worked for me, I found another solution;

Try wrapping the navigation in a timeout (of any duration)

...
setTimeout(() => {
    this._router.navigate(['EmployeeList']);
}, 0);
...

Whether or not you find this neater than including a click event is up for debate. For me, I wanted to delay the navigation to wait for an animation anyway, and this way saved me from including an otherwise redundant click event.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM