我已经编写了自定义的angular元素指令,它根据服务调用中评估的条件显示/隐藏加载指示符。该指令作为元素对元素应用。该指令运行良好,但问题是内容中应用的元素没有隐藏。
这是我的指令:
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 efp-loading-indicator ={{vm.isLoading}}>
<select> </select>
</div
我想在加载指示符存在时隐藏div的内容,在加载指示符关闭时显示。我知道我可以在子元素上使用ng-show,但我不想这样做,因为我想重用这个指令。
问题是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);
});
}
}