다음 시나리오에 대한 내 접근 방식에 어려움을 겪고 있습니다. 나는 사용자 정의 지시어 authorize
을 가지고 그룹의 이름을 전달합니다. 현재 사용자가 프로파일에이 그룹이 있으면 요소가 표시되고 그렇지 않으면 요소가 숨겨집니다. 예 :가시성에 따라 작동하는 동일한 요소의 여러 지시문
<button class="btn btn-default" role="button"
ng-click="myVm.edit()"
authorize="{{myVm.groupName}}"><!--groupName = "accountants"-->
<span class="fa fa-edit" aria-hidden="true"></span> Edit
</button>
와이 제대로 작동
namespace app.blocks.directives {
"use strict";
class AuthorizeDirective implements ng.IDirective {
public restrict: string = "A";
public replace: boolean = true;
constructor(private $compile: ng.ICompileService, private authService: services.IAuthService) {
}
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 groupName: string = (<any>instanceAttributes).authorize;
let element = angular.element(instanceElement);
let hasGroup: boolean = this.authService.hasGroup(groupName);
element.attr("ng-show", String(hasGroup));
//remove the attribute, otherwise it creates an infinite loop.
element.removeAttr("authorize");
this.$compile(element)(scope);
}
}
}
angular
.module("app.blocks.directives")
.directive("authorize", AuthorizeDirective.factory());
}
버튼이 authService가 false를 반환하는 경우 숨겨진 링크 기능 (필자는 DOM에서 작동하기 때문에)를 사용하여 타이프 라이터 authorize.ts
에서 내 원래 지침 사용자가 해당 그룹에 속하지 않으므로 (예 : "accountants"
)
내 DOM 요소에 ng-show
또는 ng-hide
지시문이있는 경우 문제가 발생합니다. 예 :
<button class="btn btn-default" role="button"
ng-hide="myVm.isDeleted"
ng-click="myVm.edit()"
authorize="{{myVm.groupName}}">
<!--groupName = "accountants"-->
<span class="fa fa-edit" aria-hidden="true"></span> Edit
</button>
때 myVm.isDeleted = true
(이것은 사용자가 내 authorize
지시에 따라 지정된 그룹에 속하지 않는 안하기 때문에 경우)가 표시됩니다 내 지침 및 DOM 요소의 결과를 무시하는 것 같다.
지시어에 우선 순위 (기본값은 0
)가 있다는 것을 알고 있습니다. 두 지침의 우선 순위가 같을 경우 문서에 따라 사전 순으로 실행됩니다. This post은이를 이해하는 데 매우 도움이되었습니다.
그래서 여기에 몇 가지 옵션이 다음 NG-숨기기 요소가 표시되어야한다고 말한다면 있지만 :
는내 권한 부여 지침 (즉 계산하기 위해
ng-hide
또는ng-show
의 조건을 평가 되세요 사용자가 특정 그룹을 가지고 있지 않다면, 그 요소는 숨겨 져야한다). 내 지시 링크의 기능에서myVm.isDeleted
에 액세스하는 방법을 찾지 못했습니다. 아무도 내가이 접근 방식에 만족할 줄 안다면.내
authorize
지시어는 다른 지시하기 전에 실행하고 나중에ng-show
또는ng-hide
(에 따라 가시성을 결정하는 각도에 의존 적이 예 : 내authorize
지시어는 사용자가에 속하지 않기 때문에 요소가 숨겨져되어야한다고 판단하는 경우 DOM 요소를 변환하고 DOM 요소를 변환해야합니다. 예를 들어ng-show="false"
을 각도로 표시하면 나중에 요소가 숨겨집니다.이 방법은 작동하지 않는 것 같습니다. DOM이 올바른 것 같습니다. 버튼이 표시됩니다. = "false"하지만 어떤 이유로 든 여전히 화면에있는 버튼을 보았습니다 그래서 Angular가 그 요소를 숨겨야한다는 것을 모르는 것처럼 보였습니다. 재미있는 점은 다른 탭으로 이동하면 되돌아갑니다 (보기가 다시로드되고 지시문이 다시 실행되는) 동일한 탭으로 이동하면 올바르게 작동합니다. 무슨 일 이니?.
public priority: number = 999; //High priority so it is executed BEFORE ng-show directive
public link(scope: ng.IScope, instanceElement: ng.IAugmentedJQuery, instanceAttributes: ng.IAttributes): void {
let groupName: string = (<any>instanceAttributes).authorize;
let element = angular.element(instanceElement);
let ngShow: string = (<any>instanceAttributes).ngShow;
let ngHide: string = (<any>instanceAttributes).ngHide;
let hasGroup: boolean = this.authService.hasGroup(groupName);
let ngHideValue = ngHide ? "!" + ngHide : "";
let ngShowValue = ngShow ? ngShow : "";
//if hasGroup, use whatever ng-show or ng-hide value the element had (ng-show = !ng-hide).
//if !hasGroup, it does not matter what value the element had, it will be hidden.
if (hasGroup) {
element.attr("ng-show", (ngShowValue + ngHideValue) || "true");
} else {
element.attr("ng-show", "false");
}
element.removeAttr("ng-hide");
//remove the attribute, otherwise it creates an infinite loop.
element.removeAttr("authorize");
this.$compile(element)(scope);
}
확실한 해결 방법은 내 버튼을 div에 넣고 div 자체에 'authorize' 지시문을 적용하고 버튼에 ng-hide를두고 버튼 자체에 여러 지시문이 충돌하지 않도록하는 것입니다. 하지만 내 질문에 대한 해결책을 찾고 angle이 왜 'ng-show = "false"를 다시 계산하지 않는지 이해하고 싶습니다. – iberodev