为啥在 Angular 指令的链接函数中“this”为空?

Posted

技术标签:

【中文标题】为啥在 Angular 指令的链接函数中“this”为空?【英文标题】:Why is "this" null, in the link function within an Angular Directive?为什么在 Angular 指令的链接函数中“this”为空? 【发布时间】:2016-04-06 07:27:04 【问题描述】:

我正在尝试使用 TypeScript 和 Angular 编写动态模板,但由于某种原因,“this”关键字始终为空,因此我无法访问我的私有成员 $compile。有任何想法吗?非常感谢! :-)

指令:

namespace ROD.Features.Player 
    "use strict";

    export class VideoDirective implements ng.IDirective 
        public restrict: string = "E";
        public replace: boolean = true;
        public scope = 
            content: "="
        ;

        constructor(private $compile: ng.ICompileService) 
        

        public link(element: JQuery, scope: ng.IScope): any 
            const youtubeTemplate = "<p>Youtube</p>";
            const vimeoTemplate = "<p>Vimeo</p>";

            var linkFn = this.$compile(youtubeTemplate);
            const content: any = linkFn(scope);
            element.append(content);
        
    

App.ts:

namespace ROD 
    "use strict";
    angular.module("rodApp", [])
        .service("Settings", [() => new Settings.DevelopmentSettings()])
        .service("RedditService", [
            "$http", "Settings",
            ($http: ng.IHttpService, settings: Settings.ISettings) => new Services.Reddit.RedditService($http, settings.sourceUrl),
        ])
        .directive("videoItem", ["$compile",
            ($compile: ng.ICompileService) => new Features.Player.VideoDirective($compile)])
        .controller("PlayerController", [
            "$scope", "RedditService",
            ($scope: any, redditService: Services.Reddit.IRedditService) => new Features.Player.PlayerController($scope, redditService),
        ]);

【问题讨论】:

我在您的代码中的任何地方都没有看到对 this 关键字的引用 - 我是不是误会了什么?您如何/曾尝试引用this 你能帮我们把它编译成纯 javascript 吗? 你能发布你遇到的错误吗? 抱歉,已经很晚了。我粘贴了错误的代码。你可以看到我在指令中使用了 this 关键字。请见上文,非常感谢。 @HenryZou:这是纯 JavaScript(第 66 行):github.com/AdrianLThomas/ROD/blob/… 【参考方案1】:

看来我对链接函数使用了错误的语法。这是正确的实现:

        public link = (element: JQuery, scope: ng.IScope): any => 
            const youtubeTemplate = "<p>Youtube</p>";
            const vimeoTemplate = "<p>Vimeo</p>";

            var linkFn = this.$compile(youtubeTemplate);
            const content: any = linkFn(scope);
            element.append(content);
        

谁能解释这是为什么? :-)

【讨论】:

ES6 箭头函数为 this: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 保留词法上下文【参考方案2】:

你需要:

    .directive("videoItem", ["$compile",
    function ($compile)  return () => new ROD.Features.Player.VideoDirective($compile); ])

而不是

    .directive("videoItem", ["$compile",
    function ($compile)  return new ROD.Features.Player.VideoDirective($compile); ])

在您的app.js 中。问题的解释在这里:http://www.michaelbromley.co.uk/blog/350/exploring-es6-classes-in-angularjs-1-x#_section-directives 问题的要点是当 Angular 调用 link 函数时,不会保留 this 的上下文。

如果您想更深入地了解该问题,只需使用 angular.js 而不是 angular.min.js 并查看调用堆栈的样子。

【讨论】:

谢谢。你的说法是有道理的——尽管它似乎不起作用,因为链接函数不再被调用。在控制台中也看不到任何错误..

以上是关于为啥在 Angular 指令的链接函数中“this”为空?的主要内容,如果未能解决你的问题,请参考以下文章

Angular中访问DOM元素的“链接”函数的等价物是啥

Angular JS:当我们已经有了具有作用域的指令控制器时,还需要指令的链接函数吗?

angular里.dirrective里的 compile啥意思

Angular 2:向动态创建的组件添加指令

Angular 指令 - 何时以及如何使用编译、控制器、预链接和后链接 [关闭]

angular源码分析 摘抄 王大鹏 博客 directive指令及系列