Angular 2 中的路由和导航

Routing and navigation in Angular 2

我正在学习 Angular 2 的教程,并且已经能够启动和 运行 一个简单的应用程序。现在,我将转到此处找到的路由和导航部分 https://angular.io/docs/ts/latest/guide/router.html,但有些东西对我不起作用。

我去了 Plunker 中的实时示例并从那里下载了代码。然后,我在 Visual Studio 2015 年设置了一个解决方案,并插入了 Plunker 下载的所有代码。该应用程序运行完美,除了一件事,导航似乎无法正常工作,因为文档似乎表明。

我开始使用 IIS Express 和 Chrome 浏览器在 Visual Studio 中调试应用程序。主页正确加载,我可以单击危机中心和英雄的 links。当我单击 link 时,组件视图正确加载并且一切看起来都很完美。

现在,如果我尝试通过简单地输入 URL 来导航,组件视图不会加载,我只有一个空白页面。

例如,我在 Visual Studio 中开始调试应用程序,Chrome 浏览器打开 URL http://localhost:56074/. The main page is loaded correctly with the "Component Router" header and the two links for "Crisis Center" and "Heroes". Now, if I simply go to the address bar and add "/crisis-center" to the end of the URL so it looks like http://localhost:56074/crisis-center,我得到一个空白页面。 Chrome 控制台显示以下错误:

GET http://localhost:56074/crisis-center 404(未找到) 导航至 http://localhost:56074/crisis-center

并且网络跟踪清楚地显示了危机中心的 404。事实上,如果我在危机中心的主页上使用导航 link 并单击它以显示危机中心组件视图,然后在危机中心视图中只需点击刷新按钮即可刷新页面,同样的结果发生了。

这是 Visual Studio 问题吗? IIS 快递?其他想法?

我们是 .Net 开发商店,我们的主要开发环境是 Visual Studio。如果这是在 Visual Studio 中使用 IIS Express 开发 Angular 2 应用程序的问题,这可能是个问题。

如果有人想尝试同样的事情,我可以压缩我的 VS 解决方案并分享。

有人在 Visual Studio 中使用 IIS Express 尝试过 Angular 2 应用程序,也许可以告诉我我做错了什么?

Angular 2 默认使用 HTML5 路由,您要么必须通过将以下内容添加到 web.config

来将所有服务器请求映射到 index.html
<rewrite>
    <rules>
        <rule name="redirect all" stopProcessing="true">
            <match url="^(.*)$" ignoreCase="false" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
            </conditions>
            <action type="Rewrite" url="PATH TO INDEX.HTML" appendQueryString="true" />
        </rule>
    </rules>
</rewrite>

或实施 HashLocationStrategy,如 angular 文档 here

中所述
provide(LocationStrategy, {useClass: HashLocationStrategy})

对于这个问题,您需要为您的应用程序使用PathLocationStrategy 或HashLocationStrategy。它在 'angular2/router'.

中可用

使用 HashLocationStrategy 的示例:

boot.ts

bootstrap(AppCmp, [
       ROUTER_PROVIDERS,
       provide(LocationStrategy, {useClass: HashLocationStrategy})
   ]);

在你的主要组件中,

class AppCmp {
          constructor(location: Location) {
          location.go(location.path());
       }

location.path()动态给出页面加载路径

除了回答: 如果你对项目中的某个路径发出ajax请求有困难,比如YOUR-DOMAIN/api/...,我建议添加如下条件:

<add input="{REQUEST_URI}" negate="true" pattern="^\/api\/.*$" ignoreCase="true" />

导致:

<rewrite>
  <rules>
      <rule name="redirect all" stopProcessing="true">
          <match url="^(.*)$" ignoreCase="false" />
          <conditions logicalGrouping="MatchAll">
              <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
              <add input="{REQUEST_URI}" negate="true" pattern="^\/api\/.*$" ignoreCase="true" />
          </conditions>
          <action type="Rewrite" url="/index.html" appendQueryString="true" />
      </rule>
  </rules>
</rewrite>

这是我的解决方案:https://csjdpw.atlassian.net/wiki/display/~Genhan.Chen/404+issue+for+Angular+2+routing

引用另一个帖子:

老问题,但我想提供这个建议作为未来读者的替代方案,因为我更喜欢重写方法:

基于 and 的答案:我使用了他们的 URL 重写建议,但我没有列出路由,而是修改了正则表达式以路由 everything 不包括我们的 Angular 2 CLI 生成的应用程序需要的文件,具有给定的扩展名(.bundle.js.bundle.map 等...):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url="^(?!.*(.bundle.js|.bundle.map|.bundle.js.gz|.bundle.css|.bundle.css.gz|.png|.jpg|.ico)).*$" />
          <conditions logicalGrouping="MatchAll">
          </conditions>
          <action type="Rewrite" url="/"  appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

我无法真正说明在 Production 环境中使用此 RegEx 解决方案的性能影响,但它对我们的 Dev 阶段 环境。

您可以通过实施哈希定位策略来修复错误:

启用 HashLocationStrategy 是这样的:

RouterModule.forRoot(routes, {useHash: true})

URL 可以包含一些以 # 字符为前缀的数据。

URL 的 # 部分称为散列片段。它从未发送到服务器,

示例:http://example.com/#/clients