如何从绝对 URL 制作 AngularDart 请求模板?

How to make AngularDart request templates from an absolute URL?

当 AngularDart 请求一个 HTML 模板时,它请求一个相对于浏览器当前 URL 的 URL。例如。如果用户当前处于 /,那么 AngularDart 可能会请求模板 URL,例如 /packages/myapp/components/mycomponent.html。但是,如果浏览器位置是 /foo/foo/bar,则 将分别从 /foo/myapp/components/mycomponent.html/foo/bar/myapp/components/mycomponent.html 请求相同的模板

这显然是不受欢迎的行为。 URLs /foo/foo/bar 仅存在于 AngularDart 路由器中(我正在使用 pushState 路由)。服务器对他们一无所知!即使服务器确实有相同名称的 URLs,它也不会有 packages 目录在所有这些目录下的符号链接或别名。

我在声明组件时尝试了绝对 URLs…

/// The top navigation bar.
@Component(
    selector: 'nav',
    templateUrl: '/static/dart/web/packages/myapp/component/nav.html',
    useShadowDom: false
)

…但是pub build抱怨。

[Warning from _Serial on myapp|web/main.dart with input myapp|lib/component/nav.dart]:
line 6, column 1 of package:myapp/component/nav.dart: Cannot cache non-package absolute URIs. /static/dart/web/packages/myapp/component/nav.html
@Component(
^^^^^^^^^^^

声明 templateUrl 的好方法是使其成为以 packages/.

开头的亲戚 URL
/// The top navigation bar.
@Component(
    selector: 'nav',
    templateUrl: 'packages/myapp/component/nav.html',
    useShadowDom: false
)

所以我似乎被迫对模板使用相对 URLs,即使浏览器的位置与服务器上存储内容的位置完全不同。

那么我应该如何告诉 AngularDart 从绝对 URL 请求这些模板,而不是构建相对于浏览器当前位置的 URL?

我 link 模板文件和 css 文件的通常方式是使用基于包目录的路径。

这是我的组件声明之一

@Component(
    selector: 'game-card',
    cssUrl: 'packages/myapp_name/components/game/game_card.css',
    templateUrl: 'packages/myapp_name/components/game/game_card.html')

并且 game_card.html 文件实际位于 /lib/components/game/game_card.html

myapp_name 是您在 pubspec.yaml

中为您的应用程序指定的名称

Angular 1

我没有理想的解决方案,但这里有一些有用的东西。我在文档级别声明了一个 <base href='…'> 元素,以便所有相关链接都将相对于该基础 URL 进行解析,而不是浏览器的位置(如问题中所述,它与实际服务器分离正在访问的资源)。

<!DOCTYPE html>
<html ng-app>
  <head>
    <title>My App</title>
    <base href="/static/dart/">
    ...

这将导致 AngularDart 模板 URLs 像 /static/dart/packages/myapp/components/mycomponent.html 一样解析为绝对 URLs,而不管浏览器的位置如何。此设置适用于我的开发环境,但需要更改基本 href 以便生产指向 pub build 工件。我从我的回答中省略了那部分,因为它是我的服务器端软件所独有的,与 Dart 或 Angular.

无关

这种方法的缺点是您将无法将相对 URL 用于其他任何事情:它们将 all 相对于<base> 元素。

Angular 2

Sigh... 18 months later and the brand-new-shiny Angular 2 has the same exact problem, except that the solution for Angular 1 doesn't work in Angular 2.

您必须注入自定义 UrlResolver,例如

import 'package:angular2/platform/browser.dart' show bootstrap;
import 'package:angular2/src/compiler/url_resolver.dart' show UrlResolver;
import 'package:angular2/src/core/di/provider.dart' show provide;
import 'package:myapp/component/app.dart' show AppComponent;

void main() {
    bootstrap(AppComponent, [
        provide(UrlResolver, useFactory:() => new UrlResolver('/static/dart/web/packages'))
    ]);
}