Angular2在模板和变化检测中起作用 [英] Angular2 functions in template and change detection

查看:107
本文介绍了Angular2在模板和变化检测中起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在服务中建立一个方法,检查导航按钮是否应该根据他的权限显示给当前用户(这只是我所知道的整体安全)。因此,这是放置在模板中的按钮。

 < 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:[
permissions:[
阅读:其中

}
},
]
}

所以在这种情况下,权限 [read:some,edit:some,read:where] 是当前登录用户需要的,以便该按钮将显示给他。 工作到目前为止!



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

解决方案

  @injectable()$ b您可以使AuthService.isAuthorized()方法返回一个承诺: $ b export class AuthService {
...
isAuthorized(arr:string []):Promise< boolean> {
return new Promise(resolve => {
//你的逻辑在这里
resolve(yourResult);
});
}
...
}

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

  @Component({
selector:your-component,
templateUrl:yourTemplate.html
})
导出类YourComponent实现OnInit {
isAuthorized:boolean;

构造函数(private authService:AuthService){}

ngOnInit(){
this.authService.isAuthorized(['some','where'])。那么(结果=> {
this.isAuthorized = result;
});




$ b $ p
$ b

在模板中,您可以使用 isAuthorized variable。

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

编辑:
如果需要AuthService.isAuthorized只能调用一次,但对于多个元素,像这样的代码可能适合您的需要:

  @Component({
选择器:your-component,
templateUrl:yourTemplate.html
})
导出类YourComponent {
isObjectAuthorized = {} as {
isFirstAuthorized:布尔;
isSecondAuthorized:boolean;
};

构造函数(private authService:AuthService){}
$ b $ checkForAuthorization(isElementAuthorized,arr:string []){
if(isElementAuthorized!== undefined){
回报;
}

this.authService.isAuthorized(arr).then(result => {
isElementAuthorized = result;
});


在你的模板中:

 < button [routerLink] =['/ some / where']
* ngIf =checkForAuthorization(isObjectAuthorized.isFirstAuthorized,[ 'some','where'])>
首先
< / button>
< button [routerLink] =['/ some / where']
* ngIf =checkForAuthorization(isObjectAuthorized.isSecondAuthorized,['some','where','else']) >
第二个
< /按钮>


Im trying to build a method inside a service that checks whether a navigation button should be showed to the current user based on his permissions or not (this is just cosmetic "security" I know). Therefore this is the button placed inside the template

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

The method AuthService.isAuthorized uses the provided array to run through all available routes and get the required permissions from the particular route's data object:

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

so in this case the permissions ["read:some","edit:some","read:where"] are needed by the current signed in user so that the button would be displayed to him. Working so far!

But since the function is called inside the template it is called multiple times because of angular change detection. How could I change my code so that the function is called only once? Even better if it would only be called once after the authentication finished writing all permissions assigned to the authenticated user into AuthService.permissions

解决方案

You can make AuthService.isAuthorized() method returns a promise:

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

You can call this method on your ngOnInit of a component (Therefore it will be called once). You pass the return value to a new variable (e.g. isAuthorized) in the component and use this variable in the template instead.

@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;
    });
  }
}

In the template you can just use isAuthorized variable.

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

Edit: If AuthService.isAuthorized() needed to be called only once but for more than one element, code like these may suits your need:

@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;
    });
  }
}

And in your template:

<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>

这篇关于Angular2在模板和变化检测中起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆