如何从绝对 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'))
]);
}
当 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/
.
/// 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'))
]);
}