Angularjs 在指令中使用隔离作用域时达到10$digest()迭代次数
我想创建一个AngularJs指令,根据一些声明进行授权 基本上,我希望在任何html元素(button、div、a等)中都有一个属性,其中我指定了哪些组可以查看项目,并且根据当前用户是否有这些组,该元素的Angularjs 在指令中使用隔离作用域时达到10$digest()迭代次数,angularjs,typescript,angularjs-scope,directive,angularjs-digest,Angularjs,Typescript,Angularjs Scope,Directive,Angularjs Digest,我想创建一个AngularJs指令,根据一些声明进行授权 基本上,我希望在任何html元素(button、div、a等)中都有一个属性,其中我指定了哪些组可以查看项目,并且根据当前用户是否有这些组,该元素的ng show设置为true或false 这是我在typescript中的指令。我正在注入一个服务,负责检查当前用户是否有以下声明: // // Directive to hide or show html element based on group claims for the curre
ng show
设置为true或false
这是我在typescript中的指令。我正在注入一个服务,负责检查当前用户是否有以下声明:
//
// Directive to hide or show html element based on group claims for the current user
//
// Usage: <button authorize="mycontroller.authorizedGroupsArray" />
//
namespace app.blocks.directives {
"use strict";
class AuthorizeDirective implements ng.IDirective {
public restrict: string = "A";
public replace: boolean = true;
public scope: any = {
authorizedGroups: "=authorize"
};
constructor(private $compile: ng.ICompileService, private authService: services.IAuthService) {
console.log("authorize directive init");
}
public static factory(): ng.IDirectiveFactory {
const directive = ($compile: ng.ICompileService, authService: services.IAuthService) =>
new AuthorizeDirective($compile, authService);
directive.$inject = [
"$compile",
"app.services.AuthService"
];
return directive;
}
public link(
scope: ng.IScope,
instanceElement: ng.IAugmentedJQuery,
instanceAttributes: ng.IAttributes): void {
let el = angular.element(instanceElement);
let groups: Array<string> = (<any>scope).authorizedGroups || [];
let authorized: boolean = this.authService.isUserAuthorized(groups); // returns true if the user has any of the groups among its claims
el.attr("ng-show", String(authorized));
//remove the attribute, otherwise it creates an infinite loop.
el.removeAttr("authorize");
this.$compile(el)(scope);
}
}
angular
.module("app.blocks.directives")
.directive("authorize", AuthorizeDirective.factory());
}
指令代码只执行一次,我将在执行后删除属性authorize
,以确保指令不会在循环中执行。所以我不太确定到底发生了什么
如果删除隔离范围(注释如下):
我尝试在指令中的authorize
属性中传递参数,如下所示:
let groups: any = instanceAttributes.authorize;
然后,此groups
变量的值不是数组本身,而是字符串literal“myCtrl.groupsAuthorized”
,该字符串无效,因为我需要的是一个组数组,而不是数组的名称
为什么隔离作用域会导致摘要错误?如何解决此问题并获取指令中的组数组
更新解决方法:
我有一个解决方法,基本上我向指令传递一个字符串,而不是数组。
我会让控制器返回一个字符串,组之间用逗号分隔:
public get groupsAuthorized(): string {
let groups: Array<string> = [
"accounting",
"administrators"
];
return groups.join(",");
}
public get groupsAuthorized():字符串{
让组:数组=[
“会计”,
“管理员”
];
返回组。加入(“,”);
}
然后我将以类似的方式使用该指令,只是这次传递了视图中首先呈现的“神奇”字符串
<button type="button" class="btn btn-default" authorize="{{myCtrl.groupsAuthorized}}">TEST</button>
测试
最后,在我的指令中,我将把逗号分隔的字符串转换成如下数组:
public link(
scope: ng.IScope,
instanceElement: ng.IAugmentedJQuery,
instanceAttributes: ng.IAttributes): void {
let groupsCommaSeparated: string = (<any>instanceAttributes).authorize;
let groups: Array<string> = groupsCommaSeparated.split(",");
let element = angular.element(instanceElement);
let authorized: boolean = this.authService.isUserAuthorized(groups);
element.attr("ng-show", String(authorized));
//remove the attribute, otherwise it creates an infinite loop.
element.removeAttr("authorize");
this.$compile(element)(scope);
}
公共链接(
经营范围:ng.IScope,
instanceElement:ng.IAugmentedJQuery,
InstanceAttribute:ng.iatAttributes):无效{
让groupsCommaSeparated:string=(instanceAttributes).authorize;
let groups:Array=groupsCommaSeparated.split(“,”);
let element=angular.element(instanceElement);
let authorized:boolean=this.authService.isUserAuthorized(组);
attr(“ng show”,字符串(已授权));
//删除该属性,否则将创建无限循环。
要素。删除交易(“授权”);
本文件为$compile(元素)(范围);
}
但这不是一个优雅的解决方案,如果逗号分隔的组的格式不正确,或者每个逗号后都有空格,则可能会导致问题!我仍然希望我的指令参数直接传递一个数组
let groups: any = instanceAttributes.authorize;
public get groupsAuthorized(): string {
let groups: Array<string> = [
"accounting",
"administrators"
];
return groups.join(",");
}
<button type="button" class="btn btn-default" authorize="{{myCtrl.groupsAuthorized}}">TEST</button>
public link(
scope: ng.IScope,
instanceElement: ng.IAugmentedJQuery,
instanceAttributes: ng.IAttributes): void {
let groupsCommaSeparated: string = (<any>instanceAttributes).authorize;
let groups: Array<string> = groupsCommaSeparated.split(",");
let element = angular.element(instanceElement);
let authorized: boolean = this.authService.isUserAuthorized(groups);
element.attr("ng-show", String(authorized));
//remove the attribute, otherwise it creates an infinite loop.
element.removeAttr("authorize");
this.$compile(element)(scope);
}