角度加载指示器自定义元素指令

时间:2016-01-08 22:50:51

标签: angularjs typescript angular-directive

我编写了自定义角元素指令,它根据服务调用评估的条件显示/隐藏加载指示符。该指令作为元素应用于元素。该指令工作正常,但问题是内容是应用元素而不是隐藏。

这是我的指令:

$redis.hincrby("alert", user_id, 1)
$redis.hincrby("messages", user_id, 1)
$redis.hincrby("notifications", user_id, 1)

以下是它的应用方式:

export interface ILoadingIndicatorAttr extends ng.IAttributes {
  efpLoadingIndicator: string;
}
 export interface ILoadingIndicatorscope extends ng.IScope {
   loading: boolean;
 }



export class LoadingIndicator implements ng.IDirective {
   public restrict: string = 'A';
   public replace: boolean = true;
   static $inject = ["$compile", "$templateRequest", "$timeout"];

constructor(public _compile: ng.ICompileService, private templateService: ng.ITemplateRequestService, private timeout: ng.ITimeoutService) {

};

link = (scope: ILoadingIndicatorscope, element: ng.IAugmentedJQuery, attrs: ILoadingIndicatorAttr, ngModel: ng.INgModelController): void => {
    var tempThis = this;
    var templateUrl: string = 'app/modules/common/directives/loadingIndicator/loadingIndicator.tmpl.html';
    attrs.$observe('efpLoadingIndicator', () => {
        if (attrs.efpLoadingIndicator == "true") {
            this.timeout(() => {
                if (attrs.efpLoadingIndicator == "true") {
                    scope.loading = true;
                    tempThis.resolveTemplate(templateUrl).then((html: ng.IAugmentedJQuery) => {
                        tempThis._compile(html)(scope).appendTo(element);                            
                    });
                }
                else {                      
                    scope.loading = false;
                }
            }, 1000);
        }
        else {
            scope.loading = false;
        }
    });
}

resolveTemplate = (templateUrl: string): ng.IPromise<ng.IAugmentedJQuery> => {
    return this.templateService(templateUrl).then((html: string) => {
        return angular.element(html);
    });
   }
}

我想在加载指示符存在时隐藏div的内容,在加载指示符关闭时显示。我知道我可以在子元素上使用ng-show但不想这样做,因为我想重用这个指令。

1 个答案:

答案 0 :(得分:0)

问题是this不是您在链接功能中所期望的。此时,this将引用window对象(因此tempThis也是如此)。

如果您需要使用link函数,则必须在构造函数中将其重新绑定到this,其中this指的是类:

export interface ILoadingIndicatorAttr extends ng.IAttributes {
   efpLoadingIndicator: string;
}

export interface ILoadingIndicatorscope extends ng.IScope {
   loading: boolean;
}

export class LoadingIndicator implements ng.IDirective {
   public restrict: string = 'A';
   public replace: boolean = true;
   link:(scope: ILoadingIndicatorscope, element: ng.IAugmentedJQuery, attrs: ILoadingIndicatorAttr, ngModel: ng.INgModelController)=> void

   static $inject = ["$compile", "$templateRequest", "$timeout"];

constructor(public _compile: ng.ICompileService, private templateService: ng.ITemplateRequestService, private timeout: ng.ITimeoutService) {
    this.link = this.myLink.bind(this);
};

myLink(scope: ILoadingIndicatorscope, element: ng.IAugmentedJQuery, attrs: ILoadingIndicatorAttr, ngModel: ng.INgModelController): void => {
    var tempThis = this;
    var templateUrl: string = 'app/modules/common/directives/loadingIndicator/loadingIndicator.tmpl.html';
    attrs.$observe('efpLoadingIndicator', () => {
        if (attrs.efpLoadingIndicator == "true") {
            this.timeout(() => {
                if (attrs.efpLoadingIndicator == "true") {
                    scope.loading = true;
                    tempThis.resolveTemplate(templateUrl).then((html: ng.IAugmentedJQuery) => {
                        tempThis._compile(html)(scope).appendTo(element);                            
                    });
                }
                else {                      
                    scope.loading = false;
                }
            }, 1000);
        }
        else {
            scope.loading = false;
        }
    });
}

resolveTemplate = (templateUrl: string): ng.IPromise<ng.IAugmentedJQuery> =>{
    return this.templateService(templateUrl).then((html: string) => {
        return angular.element(html);
    });
   }
}
相关问题