模板为<script type ="text/ng-template">等效于角度2

Oli*_*ier 12 angular

Angularjs(例如angular 1)具有搜索<script type ="text/ng-template">元素的这种方便行为,该元素在向服务器请求之前具有给定模板url的id.

例如:下面的代码不会触发任何其他http请求

<script type="text/ng-template" id="mytemplate.html">
  This is a body for my template
</script>
<script>
    //...
    app.directive('myComponent', function() {
        return {
            templateUrl: 'mytemplate.html'  // does NOT trigger a http get
        };
    });
</script>
Run Code Online (Sandbox Code Playgroud)

使用Angular 2似乎不起作用.

@View({
   templateUrl: 'mytemplate.html',  // will be fetched from server !
})
class MyComponent{}
Run Code Online (Sandbox Code Playgroud)

有没有另一种方法来实现它?我错过了什么吗?

ps:我不希望在我的ts文件中嵌入我的所有html ...

Oli*_*ier 7

如果有人有兴趣,我发现了一个简单的解决方法(更清洁的解决方案会更好)

function template(url, viewdef) {
    var elt = document.getElementById(url);
    if (elt && elt.getAttribute('type') == 'text/ng-template') {
        viewdef.template = elt.innerHTML;
    } else
        viewdef.templateUrl = url;
    return viewdef;
}

@View(template('mytemplate.html', {
    directives: [NgIf /*required directives*/]
}))
class MyComponent{}
Run Code Online (Sandbox Code Playgroud)

但它假定加载此脚本时<script>已存在.

[编辑]更好的解决方法

我想出了一个简单的想法,就是覆盖@View装饰工厂.

1)创建一个 viewoverride.ts文件

import * as ng from 'angular2/core'
let oldNgView = ng.View;
function ViewOverride(viewDef) {
    if (typeof viewDef.templateUrl == "string") {
        let elt = document.getElementById(viewDef.templateUrl);
        if (elt && elt.getAttribute('type') == 'text/ng-template') {
            viewDef.template = elt.innerHTML;
            delete viewDef.templateUrl;
        }
    }
    return oldNgView(viewDef);
}
ng.View = <ng.ViewFactory>ViewOverride;
Run Code Online (Sandbox Code Playgroud)

nb:将它放在一个单独且独立的文件中非常重要,以强制它在其他导入之前执行

2)并将其作为引导程序文件的第一行:

import './viewoverride'
Run Code Online (Sandbox Code Playgroud)

3)就是这样.@View表示法现在被覆盖

@View({templateUrl:'mytemplate.template'}) class MyClass{} 
Run Code Online (Sandbox Code Playgroud)

现在将寻找id为的脚本元素 mytemplate.template