angularjs - TypeLite-generering med tillägg av hierarkiskt beroende
Jag använder för närvarande en klientversion med AngularJS 1.x i TypeScript och en AspNet WebApi-backend i C#.
För kommunikation med backend använder jag $resource-tjänsten från Angular. Genom att använda denna tjänst måste mina modellgränssnitt som genereras med TypeLITE utvidga
ng.resource.IResource<IModel>
Är det möjligt att automatiskt utöka alla genererade modellgränssnitt från detta gränssnitt som beskrivs av Angular?
Annars måste allt göras separat på det här sättet
export interface Model extends ng.resource.IResource<Model> {
}
Stort tack på förhand, MacX
Svar #1
Detta är inte en enkel uppgift. Ett alternativ är att skapa en anpassad TsModelVisitor som lägger till en dummyklass ng.resource.IResource<T> i kodmodellen och ändrar basklassen för alla andra klasser i kodmodellen.
Jag skulle försöka följande steg:
skapa en klass som härstammar från TsModelVisitor
- i
VisitModel-metoden skapa en nyTsClass-modell som representerar Angular-modellgränssnittet
- i
- i
VisitClass-metoden, sättBaseTypetill den klass som skapades iVisitModel-metoden för varje klass
anropa din modellbesökare i .tt-fil
var ts = TypeScript.Definitions()
.AsConstEnums(false);
var model = ts.ModelBuilder.Build();
model.RunVisitor(new YourModelVisitor());
istället för <#= ts.Generate(TsGeneratorOutput.Properties) #> använd '<#= ts.ScriptGenerator.Generate(model, TsGeneratorOutput.Properties) #>' för att generera utdata
Svar #2
Det enklaste sättet att uppnå detta är att utöka TsGenerator. Skapa en fil med namnet TsAngularJsModelGenerator.ttinclude i samma katalog som din TypeLite.Net4.tt-fil och klistra in följande:
<#@ assembly name="$(TargetDir)\TypeLite.dll" #>
<#@ assembly name="$(TargetDir)\TypeLite.Net4.dll"#>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="TypeLite" #>
<#@ import namespace="TypeLite.TsModels" #>
<#+
class TsAngularJsModelGenerator : TsGenerator
{
protected override void AppendClassDefinition(TsClass classModel, ScriptBuilder sb, TsGeneratorOutput generatorOutput)
{
string typeName = this.GetTypeName(classModel);
string visibility = this.GetTypeVisibility(classModel, typeName) ? "export " : "";
sb.AppendFormatIndented("{0}interface {1}", visibility, typeName);
if (classModel.BaseType != null)
{
sb.AppendFormat(" extends {0}", this.GetFullyQualifiedTypeName(classModel.BaseType));
}
else
{
sb.AppendFormat(" extends ng.resource.IResource<{0}>", typeName);
}
sb.AppendLine(" {");
var members = new List<TsProperty>();
if ((generatorOutput & TsGeneratorOutput.Properties) == TsGeneratorOutput.Properties)
members.AddRange(classModel.Properties);
if ((generatorOutput & TsGeneratorOutput.Fields) == TsGeneratorOutput.Fields)
members.AddRange(classModel.Fields);
using (sb.IncreaseIndentation())
{
foreach (var property in members)
{
if (property.IsIgnored)
continue;
var propTypeName = this.GetPropertyType(property);
sb.AppendLineIndented(string.Format("{0}: {1};", this.GetPropertyName(property), propTypeName));
}
}
sb.AppendLineIndented("}");
_generatedClasses.Add(classModel);
}
} #>
Observera: Du kommer förmodligen att behöva ändra de första två raderna så att de pekar på en giltig plats för dig (jag upptäckte att under MVC innehåller inte alltid bin-katalogen TypeLite.dll och TypeLite.Net4.dll-filerna - om du stöter på problem, kom ihåg att sätta värdet på debug till true på den första raden i TypeLite.Net4.tt-filen för att få bättre diagnostik).
Lägg sedan till följande rad i din TypeLite.Net4.tt-fil under raden <#@include file="Manager.ttinclude"#>:
<#@include file="TsAngularJsModelGenerator.ttinclude"#>
Slutligen, i filen TypeLite.Net4.tt ändra anropet till TypeScript.Definitions och skicka en ny instans av TsAngularJsModelGenerator som följer:
<# var ts = TypeScript.Definitions(new TsAngularJsModelGenerator())
.WithReference("Enums.ts")
.ForLoadedAssemblies();
#>
