2015-11-12 8 views
12

angularjs (np kątowej 1) miało to wygodny zachowania poszukiwania typu < skryptu = „text/ng szablon” > elementu który miał identyfikator podanego szablonu URL, zanim zażądał go na serwer.jako szablon <skryptu type = „text/ng matrycy”> równoważne z kątowych 2

Ex: Poniższy kod nie powoduje żadnego dodatkowego żądania 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> 

nie wydaje się działać przy użyciu kątowa 2.

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

Czy istnieje inny sposób go zrealizować? Czy czegoś brakuje?

ps: i nie chcą embbed całe html w moich plików ts ...

+0

Możesz użyć 'template' zamiast' templateUrl'. –

+0

@EricMartinez to co miałem na myśli przez "nie chcę osadzać mojego html": Generuję szablon z widoku aspnet (maszynki do golenia) ... nie można go osadzać w pliku js. Nie jest też wygodne edytowanie html w ciągu znaków js. – Olivier

+0

jest o wiele bardziej wygodna, ponieważ możesz używać wstecznego kliknięcia .. – foxx

Odpowiedz

7

Jeśli ktoś jest zainteresowany, znalazłem proste obejście (czystsze rozwiązanie byłoby lepiej, choć)

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{} 

Zakłada się jednak, że skrypt > jest już obecny podczas ładowania tego skryptu.

[EDIT] Lepsze obejście

po prostu wpadł na prosty pomysł, aby po prostu zastąpić fabrykę @View dekorator.

1) Utwórz plik 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: To jest bardzo ważne, aby umieścić go w oddzielnym i niezależnym pliku, aby go zmusić do wykonania przed innymi importu

2) i umieścić to jako pierwszy linii swojego pliku uruchamiającego:

import './viewoverride' 

3) To wszystko. Notacja @View jest teraz nadpisane

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

będzie teraz szukać elementu skryptu który id jest mytemplate.template

+0

Innym rozwiązaniem byłoby użycie Gulp do tworzenia procesu sprzedaży pakietowej. – Vincent

+0

@ Vincent Jak wspomniano w moim komentarzu do wpisu na pytanie, to nie jest opcja: Generuję szablony w czasie wykonywania. – Olivier

+0

Co zrobić, jeśli wiele szablonów ng na jednej stronie? .. jest to możliwe? –

4

myślę czystszy sposób byłoby jeśli podasz twój zwyczaj ViewResolver, zainspirowany kątowe beta 17 jest kod źródłowy, coś w linii:

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

Powiązane problemy