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

时间:2015-11-12 13:43:09

标签: angular

Angularjs(例如,角度1)在请求之前搜索具有给定模板URL的id的&lt; script type =“text / ng-template”&gt; 元素具有这种方便的行为它到服务器。

&#xA;&#xA;

例如:下面的代码没有触发任何额外的http请求

&#xA;&#xA;
  &lt; script type =“text / ng-template”id =“mytemplate.html”&gt;&#xA;这是我的模板的主体&#xA;&lt; / script&gt;&#xA;&lt; script&gt;&#xA; //...
 app.directive('myComponent',function(){&#xA; return {&#xA; templateUrl:'mytemplate.html'//不会触发http get&#xA;};&#xA;});& #xA;&lt; / script&gt;&#xA;  
&#xA;&#xA;

使用Angular 2似乎不起作用。

&#xA;& #xA;
  @View({&#xA; templateUrl:'mytemplate.html',//将从服务器获取!&#xA;})&#xA; class MyComponent {}&#xA ;  
&#xA;&#xA;

还有其他方法可以实现吗?我错过了什么吗?

&#xA;&#xA;

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

& #xA;

2 个答案:

答案 0 :(得分: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{}

但它假设&lt; script&gt;加载此脚本时已存在。

[编辑]更好的解决方法

我想出了一个简单的想法,就是覆盖@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;

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

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

import './viewoverride'

3)那就是它。 @View表示法现在被覆盖

@View({templateUrl:'mytemplate.template'}) class MyClass{} 

现在将寻找id为mytemplate.template

的脚本元素

答案 1 :(得分:4)

我认为更简洁的方法是,如果您提供自定义的ViewResolver,受到角色 beta 17 的源代码的启发,有以下几行:

import { Type, ViewMetadata, Reflector, Injectable, ComponentMetadata } from 'angular2/core';
import { ViewResolver } from 'angular2/compiler';

const SCRIPT_TYPE_NAME = 'text/ng2-template';

@Injectable()
export class CustomViewResolver extends ViewResolver 
{
  constructor(private _r: Reflector){ super() }
  resolve(component: Type): ViewMetadata
  {
    let annotations = this._r.annotations(component);
    annotations.forEach( cm => 
    {
      if(cm instanceof ComponentMetadata && cm.templateUrl && typeof cm.templateUrl == 'string' )
      {
        let elemTpl = (<any>document).getElementById(cm.templateUrl);
        if( elemTpl && elemTpl.getAttribute('type') == SCRIPT_TYPE_NAME )
        {
          cm.template = elemTpl.innerHTML;
          elemTpl.remove();
          cm.templateUrl = undefined
        }
        else
          throw new Error(`template "${cm.templateUrl}" not found among html scripts`)
      }
    })
    return super.resolve(component)
  }
}

Plunker Link