【问题标题】:Angular refresh the application if the URL is written manually如果 URL 是手动编写的,则 Angular 刷新应用程序
【发布时间】:2018-12-12 14:33:36
【问题描述】:

我正在使用 Angular 6,但在更改路线时遇到了问题。 如果我使用 routerLink 或 navigate() 方法浏览应用程序,它可以正常工作,因为它只加载新模块(如果需要)。 但例如,如果我在这个链接中:localhost:8080/home,我点击 URL,取消 'home',写 'profile' 并按 Enter,它会正确进入配置文件页面,但重新加载应用程序(也是应用程序组件)。为什么?我想不通。 这是我的路线:

const appRoutes: Routes = [
  { path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
  { path: 'profile', component: ProfileComponent, canActivate: [AuthGuard] },
  { path: 'login', component: LoginComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

也许问题出在 auth-guard 上?

@Injectable()
export class AuthGuard implements CanActivate {

constructor(private store: Store<fromApp.AppState>, private route: ActivatedRoute, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.store.select('auth')
        .pipe(take(1),
            map((authState: fromAuth.State) => {
                if (authState.authenticated) {
                    return true;
                } else {
                    let sessionStorageToken: string = sessionStorage.getItem('token');
                    if (sessionStorageToken) {
                        this.store.dispatch(new AuthActions.Login());
                        this.store.dispatch(new AuthActions.SetToken(sessionStorageToken));
                        return true;
                    } else {
                        let url = state.url;
                        this.router.navigate(['/login', { redirectTo: url }]);
                        return false;
                    }
                }
            }));
}
}

这是 profile.module.ts:

@NgModule({
declarations: [
    ProfileComponent
],
imports: [
    CommonModule,
    FormsModule
]
 })
 export class ProfileModule { }

【问题讨论】:

  • 您必须按两次回车键。我不知道为什么,我从来没有研究过。之后有目的吗?你想达到什么目标?
  • 这是我在 Angular 中的第一个项目,通常我使用 AngularJS..在 AngularJS 中,例如,如果我在家,然后我去配置文件,然后我回家(也通过 url 手动)页面和应用程序未重新加载!问题是我使用 Redux 来管理状态和登录用户,所以如果我转到“个人资料”页面并且重新加载了应用程序,我会丢失关于登录用户的状态部分
  • 对于任何投反对票的人:我很高兴这个问题从未发生在您身上。

标签: angular angular-routing angular-router canactivate


【解决方案1】:

我回答这个问题有点晚了,但也许这也会对某人有所帮助。

您可以创建一个 .htaccess 文件,它将所有请求传输到您的 index.html 文件

.htaccess

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

【讨论】:

    【解决方案2】:

    你可以使用

    RouterModule.forRoot(
      ROUTES,
      { useHash: true }
    )],
    

    哈希将阻止应用程序重新加载。 因此,当您在地址栏上按 Enter 时,应用程序只会更改要显示的组件。

    【讨论】:

    • 它工作正常(Angular 12),这就是我想要的......!这种重新加载导致内存中的信息丢失(即使容器对象是单例的)并且它总是最终再次请求登录
    【解决方案3】:

    使用 routerLink 时,JavaScript 会改变 URL ,即不视为重新加载网页。

    但是,当您在地址栏中按回车键时,页面会重新加载,即再次从提供 index.html 的服务器提供内容(如果您没有定义任何其他要提供的 HTML位置),因此应用程序重新初始化。

    这就是重新加载所有组件的原因。

    根据@Wesley 的建议,您可以参考 angular 文档了解更多信息。

    https://angular.io/guide/router

    您可以浏览下面提到的博客以进行部署。

    https://arjunphp.com/deploy-angular-app-production-nginx/

    这里要注意的主要是try_files $uri $uri/ /index.html =404;。当在地址栏上按下回车键时,NGINX 首先检查给定的 URL 是否映射到服务器上的某个文件/路由。如果它不存在,在我们的例子中localhost:8080/profile,则不存在,因为没有这样的物理路径。因此,NGINX 会为/index.html 文件提供服务,该文件又会获取所有 JS 文件,这些文件将依次处理路由。

    如果你需要使用 API,你可以使用 NGINX 的反向代理机制来重定向,例如,/api/ 路径到你对应的服务器。

    【讨论】:

      【解决方案4】:

      路由基本上用于延迟加载应用程序,一次一个模块。 每条路线都依赖于前一条路线,依此类推。 所以当你手动输入一个 url 时,应用会重新加载路由中的所有组件。

      【讨论】:

        【解决方案5】:

        当您在 Angular 中浏览 routerLink 时,底层 JavaScript 正在确定向浏览器提供什么。这意味着当通过 Angular 路由器更改 URL 地址时,它会接收更改并相应地为组件提供服务。

        当您手动更新 URL 并按 Enter 键时,就像进入一个新网页一样。这意味着服务器需要重新为基础网站http://localhost:1234 提供服务,然后应用程序将处理之后的路由/profile 并提供所需的组件。

        我试图用一种非常简单的方式来解释它,更详尽的解释请查看Angular docs

        【讨论】:

        • 但是为什么 AngularJS 的行为不同呢?使用 AngularJS 从来没有发生在我身上!可能是为了 ng-serve?
        • 是因为网址中曾经有一个#
        • 该死的你是对的!!添加: {useHash: true} 它有效!现在的选择是.. 是否使用哈希?也许删除 ProfileModule 并将其包含在 CoreModule 中它无需刷新即可工作,或者问题会持续存在?
        • 您可以删除哈希。在这种情况下,您必须配置服务器以处理此类请求。
        • @chris - 这是本地存储的用途:)
        猜你喜欢
        • 2018-10-18
        • 2019-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-21
        • 1970-01-01
        • 2015-12-02
        相关资源
        最近更新 更多