【问题标题】:Angular2 functions in template and change detection模板中的 Angular2 函数和更改检测
【发布时间】:2017-03-08 01:25:18
【问题描述】:

我试图在服务中构建一个方法,用于检查是否应根据当前用户的权限向当前用户显示导航按钮(我知道这只是装饰性的“安全性”)。因此,这是放置在模板内的按钮

<button [routerLink]="['/some/where']"
        *ngIf="AuthService.isAuthorized(['some', 'where'])">
    Personen
</button>

AuthService.isAuthorized 方法使用提供的数组遍历所有可用路由并从特定路由的数据对象中获取所需的权限:

{
    path: 'some',
    component: SomeComponent,
    data: {
        permissions: [
            "read:some",
            "edit:some"
        ]
    },
    children: [
        {
            path: 'where',
            component: SomeComponent,
            data: {
                permissions: [
                    "read:where"
                ]
            }
        },
    ]
}

所以在这种情况下,当前登录用户需要权限["read:some","edit:some","read:where"],以便向他显示按钮。 工作至今!

但是由于该函数在模板内部被调用,因此由于角度变化检测而被多次调用。我怎样才能更改我的代码,以便只调用一次函数?如果它只在身份验证完成后将所有分配给经过身份验证的用户的权限写入 AuthService.permissions

时才被调用,那就更好了

【问题讨论】:

    标签: function angular templates


    【解决方案1】:

    你可以让 AuthService.isAuthorized() 方法返回一个承诺:

    @injectable()
    export class AuthService {
      ...
      isAuthorized(arr: string[]): Promise<boolean> {
        return new Promise(resolve =>{
          // your logic here
          resolve(yourResult);
        });
      }
      ...
    }
    

    您可以在组件的ngOnInit 上调用此方法(因此它将被调用一次)。您将返回值传递给组件中的新变量(例如isAuthorized),并在模板中使用此变量。

    @Component({
    selector: "your-component",
    templateUrl: "yourTemplate.html"
    })
    export class YourComponent implements OnInit {
      isAuthorized: boolean;
    
      constructor(private authService: AuthService) {}
    
      ngOnInit() {
        this.authService.isAuthorized(['some', 'where']).then(result => {
          this.isAuthorized = result;
        });
      }
    }
    

    在模板中你可以只使用isAuthorized 变量。

    <button [routerLink]="['/some/where']"
        *ngIf="isAuthorized">
    Personen
    </button>
    

    编辑: 如果 AuthService.isAuthorized() 只需要调用一次但不止一个元素,这样的代码可能适合您的需要:

    @Component({
    selector: "your-component",
    templateUrl: "yourTemplate.html"
    })
    export class YourComponent {
      isObjectAuthorized = {} as {
        isFirstAuthorized: boolean;
        isSecondAuthorized: boolean;
      };  
    
      constructor(private authService: AuthService) {}
    
      checkForAuthorization(isElementAuthorized, arr: string[]) {
        if (isElementAuthorized !== undefined) {
          return;
        }
    
        this.authService.isAuthorized(arr).then(result => {
          isElementAuthorized = result;
        });
      }
    }
    

    在你的模板中:

    <button [routerLink]="['/some/where']"
        *ngIf="checkForAuthorization(isObjectAuthorized.isFirstAuthorized, ['some', 'where'])">
    First
    </button>
    <button [routerLink]="['/some/where']"
        *ngIf="checkForAuthorization(isObjectAuthorized.isSecondAuthorized, ['some', 'where', 'else'])">
    Second
    </button>
    

    【讨论】:

    • 所以这有助于只运行一次函数。问题是该功能不仅应该用于一个元素,而且应该用于某些不同的元素。 &lt;button [routerLink]="['/some/where']" *ngIf="auh.isAuthorized(['some', 'where'])"&gt;First&lt;/button&gt;&lt;button [routerLink]="['/some/where/else']" *ngIf="auh.isAuthorized(['some', 'where', 'else'])"&gt;Second&lt;/button&gt;。 @samAlvin 您的解决方案需要我为我想在 ngOnInit 方法内使用它的每个元素调用该函数,并为组件内的每个元素创建一个 isAuthorizedElementName 属性。
    • @MaxSolid 我已经编辑了我的答案,为不同的元素添加了解决方案
    猜你喜欢
    • 1970-01-01
    • 2016-09-25
    • 2017-10-03
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 2016-09-13
    相关资源
    最近更新 更多