Angularjs+Typescript 指令实现 $compile

Posted

技术标签:

【中文标题】Angularjs+Typescript 指令实现 $compile【英文标题】:Angularjs+Typescript directive implementing $compile 【发布时间】:2015-08-24 01:26:14 【问题描述】:

我在以下指令中注入 $compile 时遇到问题。

export class Element 
    public link(scope:dirScopeInterface, element:any, attrs:ng.IAttributes, formCtrl:ng.IFormController) 
        var attr = this.arrayJoiner(scope.standard, scope.attrs || , scope.ignore || );
        element.html(this.compiler(attr));
        $compile(element.contents())(scope);
    

目前它正在抛出 $compile is undefined 错误。我尝试过使用

static $inject = ['$compile'];

但由于某种原因,它从转译的脚本中消失了。

Here 是使用的完整代码。

【问题讨论】:

【参考方案1】:

我使用 AngularJS + Typescripts 实现 jQuery 向导步骤

它应该也适用于其他 $compile 函数。

AppDirective.ts

 export class stepwizard implements ng.IDirective 
    constructor() 
        console.log("construtor step wizard directive");
    

    link($scope: ng.IScope, $element: JQuery, attributes: ng.IAttributes, ngModel: ng.INgModelController, ctrl: any) 
        console.log("start step wizard link function");
        $element.wrapInner('<div class="steps-wrapper">');
        const steps = $element.children(".steps-wrapper").steps(
            headerTag: "h3",
            bodyTag: "section",
            transitionEffect: "slideLeft",
            autoFocus: true
        );
        const compiled = ctrl.$compile(steps);
    

    public static Factory() 
        var directive = () => 
            return new stepwizard();
        ;

        directive.$inject = ['$compile'];
        console.log("initial step wizard");

        return directive;
    

AppController.ts

    export class pageController
    // your declaraction
    static $inject: Array<string> = [
      $compile',
    ];
    constructor(
      $compile: ng.ICompileService,
    ) 
    // your constructor declaraction
    

HTML

// sample take from official website
             <div stepwizard>
                <h3>Keyboard</h3>
                <section>
                    <p>Try the keyboard navigation by clicking arrow left or right!</p>
                </section>
                <h3>Effects</h3>
                <section>
                    <p>Wonderful transition effects.</p>
                </section>
                <h3>Pager</h3>
                <section>
                    <p>The next and previous buttons help you to navigate through your content.</p>
                </section>
            </div>

directives.stepwizard = <namespace>.directives.stepwizard.Factory();
app.directive(directives);

【讨论】:

【参考方案2】:

包括static $injectconstructor

export class Element 

    // $compile can then be used as this.$compile
    constructor(private $compile: ng.ICompileService);

    public link(scope:dirScopeInterface, element:any, attrs:ng.IAttributes, formCtrl:ng.IFormController) 
        var attr = this.arrayJoiner(scope.standard, scope.attrs || , scope.ignore || );
        element.html(this.compiler(attr));
        this.$compile(element.contents())(scope);
    

编辑

用angular注册这个指令,这是我一直做的(有多种解决方案):

export class Element implements angular.IDirective 

    public static ID = "element";

    // This can then be removed:
    // static $inject = ["$compile"];

    // ..

    /**
     * The factory function that creates the directive
     */
    static factory(): angular.IDirectiveFactory 
        const directive = ($compile) => new Element($compile);
        directive.$inject = ["$compile"];
        return directive;
    

并注册:

angular.module("myModule" [])
    .directive(Element.ID, Element.factory());

【讨论】:

当构造函数需要参数时,我如何使用 angular 注册这个指令?我也按照您指定的方式实现了它,但得到 $compile is not a function 错误。 Angular 使用依赖注入,因此构造函数会自行解析。您必须使用指向控制器的指针来访问私有 $compile 变量:this.$compile 看起来像下面这样:static $inject = ['$compile'];构造函数(私有 $compile:ng.ICompileService) 公共链接 =(范围:dirScopeInterface,元素:any,attrs:ng.IAttributes,formCtrl:ng.IFormController)=> scope.tempForm = formCtrl; var attr = this.arrayJoiner(scope.standard, scope.attrs || , scope.ignore || ); element.html(this.compiler(attr)); this.$compile(element.contents())(scope); Angular 抛出 $compile not a function 错误。 我已经添加了我总是如何注册这样的打字稿指令 @devqon:我在哪里可以找到Directive,在new Directive 中使用?【参考方案3】:

所以我找到了一种让它工作的方法,但它并不像我希望的那样优雅。

angular.module('formDirectives', [], function($compileProvider)
    $compileProvider.directive('catElement', ($compile) => 
        return new Element($compile);
    );
)

【讨论】:

以上是关于Angularjs+Typescript 指令实现 $compile的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS TypeScript 指令链接函数

AngularJs + typescript 指令依赖注入

带有 ControllerAs 和 TypeScript 类的 AngularJs 指令

如何使用 TypeScript 解决 AngularJS 指令

AngularJS 和 Typescript:如何将类/类型分配为指令的控制器?

在 AngularJS 上使用 Typescript 的指令中控制器的范围