AngularJS Typescript-direktiv
Har problem med att skapa nästlade direktiv med Typescript. Jag kan göra det i enkel AngularJs: http://plnkr.co/edit/UruTqEdMnqNT5wjxcQNC?p=preview,
men när jag använder TypeScript får jag felmeddelandet "Ingen kontrollant".
/// <reference path="../../Scripts/AngularJs/Typings/angular.d.ts" />
export class directiveA {
public static $inject: Array<string> = [];
constructor() {
var directive: ng.IDirective = {};
directive.priority = 0;
directive.restrict = "A";
directive.scope = {};
directive.transclude = true;
directive.templateUrl = "otherTemplate.html";
directive.replace = true;
directive.controller = function ($scope, $element) {
this.flip = function () {
$element.toggleClass("flipped");
}
}
directive.replace = true;
return directive;
}
}
export class directiveB{
public static $inject: Array<string> = [];
constructor() {
var directive: ng.IDirective = {};
directive.require = "^directiveA";
directive.priority = 1;
directive.restrict = "A";
directive.scope = {
simplrSide : "@"
};
directive.transclude = true;
directive.templateUrl = "templeUrl.html";
directive.link = function (scope, iElement, iAttrs, simplrEditable) {
scope.flip = function () {
simplrEditable.flip();
}
}
directive.replace = true;
return directive;
}
}
Jag vet inte om det är relevant, men jag använder AMD Require.JS för att ladda skript
Svar #1
Förutsatt att du registrerar dessa som:
import mod = require('yourfile')
youmodule.directive('directiveA',mod.directiveA);
youmodule.directive('directiveB',mod.directiveB);
Det borde fungera så länge din HTML ser ut så här:
<div directiveA>
<div directiveB>
</div>
</div>
Några anteckningar utöver det:
Använd funktioner för dina direktivdefinitioner.
Detta beror på att direktiv (till skillnad från kontroller) kallas utan new-operatorn. Så om du har något som:
class Test{
foo = "EAC";
constructor(){
var directive:any = {};
directive.restrict = this.foo;
}
}
Det kompileras till felaktig javascript. Eftersom funktionen Test anropas utan new-operatorn betyder det att this hänvisar till window och inte en instans av klassen. Så du kan ändå inte använda något som är definierat utanför konstruktorn. Jag rekommenderar något som:
function foo():ng.IDirective{
return {
restrict: 'EAC';
}
}
På det här sättet kommer TypeScript att hjälpa dig skriva korrekt JavaScript för Angular istället för att leda dig åt fel håll. Jag kommer att göra en video om detta vid något tillfälle
Använd klasser för din controller Controllers inuti direktiv kallas också med new-operatorn. Precis som controllers utanför: http://www.youtube.com/watch?v=WdtVn_8K17E Låt Typescript hjälpa dig med betydelsen av this inuti controller-definitionen. Dessutom kan du använda typen för controllern i det barn direktivet något som (för typ-säkerhet och inferens):
link: function (scope, iElement, iAttrs, simplrEditable:YourControllerClass)
För injektion i direktivfunktioner använder jag fortfarande $inject. Jag har följande gränssnittsdefinition :
interface Function{
$inject:string[]
}
Detta betyder att du kan göra :
foo.$inject = ['$compile']; // e.g
Svar #2
Problemet är inte relaterat till Typescript, utan till AngularJS-direktiv. Att ändra templateUrl till template och använda inbäddad kod hjälper till att lösa felen. Det är ett AngularJS-problem, mer om det: https://github.com/angular/angular.js/issues/1903 Hoppas de kommer att fixa detta i framtiden!
export class directiveA {
public static $inject: Array<string> = [];
constructor() {
var directive: ng.IDirective = {};
directive.priority = 0;
directive.restrict = "A";
directive.scope = {};
directive.transclude = true;
directive.template = "<div>Your content</div>";
directive.replace = true;
directive.controller = function ($scope, $element) {
this.flip = function () {
//Some func
}
}
directive.replace = true;
return directive;
}
}
