如何从绝对URL生成AngularDart请求模板?

时间:2015-02-23 22:37:45

标签: dart angular-dart

当AngularDart请求HTML模板时,它会请求相对于broswer当前URL的URL。例如。如果用户当前位于/,则AngularDart可能会请求/packages/myapp/components/mycomponent.html之类的模板网址。但如果浏览器位置为/foo/foo/bar,则分别从/foo/myapp/components/mycomponent.html/foo/bar/myapp/components/mycomponent.html请求相同的模板

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

我在声明组件时尝试了绝对URL ...

/// 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
)

所以看起来我被迫使用模板的相对URL,即使浏览器的位置完全脱离了服务器上存储内容的位置。

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

2 个答案:

答案 0 :(得分:2)

我链接模板文件和css文件的常用方法是使用基于packages目录的路径。

这是我的组件声明之一

@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

中为您的应用提供的名称

答案 1 :(得分:1)

Angular 1

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

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

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

这种方法的缺点是您无法使用相对URL进行其他任何操作:它们将所有解析为<base>元素。< / p>

Angular 2

  叹息...... 18个月之后,全新闪亮的Angular 2有着同样的问题,除了Angular 1的解决方案在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'))
    ]);
}