Angular 角度4:用作全局变量的指令

Angular 角度4:用作全局变量的指令,angular,typescript,Angular,Typescript,我想创建一个可以使用模板变量的指令,这样我就可以访问全局变量,类似于Angular.JS中的$rootScope,而不必在每个需要变量的组件中注入服务 例如: @Directive({ selector: '[app]', exportAs: 'app' }) export class AppDirective { isLoggedIn: boolean = false; constructor() { // Do some stuff to s

我想创建一个可以使用模板变量的指令,这样我就可以访问全局变量,类似于Angular.JS中的
$rootScope
,而不必在每个需要变量的组件中注入服务

例如:

@Directive({
    selector: '[app]',
    exportAs: 'app'
})
export class AppDirective {
    isLoggedIn: boolean = false;

    constructor() {
        // Do some stuff to set 'this.ready'...
    }
}
我希望能够在我的模板中使用上述代码,如下所示:

<div #app>
    <div *ngIf="app.isLoggedIn">...</div>
</div>

...

这样做可能吗?

看看这种方法:

如果您可以在.ts文件中使用模板,并且可以执行类似操作(从该帖子复制),请执行以下操作:

创建全局类:

export class Globals {
    isLoggedIn = true;
}
然后使用此组件:

import { Globals } from './globals';

@Component({
    selector: 'my-app',
    template: `<h1>My Component {{globals.isLoggedIn}}<h1/>`
})
export class AppComponent {
    constructor(){
    }
}
从“/Globals”导入{Globals};
@组成部分({
选择器:“我的应用程序”,
模板:`My Component{{globals.isLoggedIn}`
})
导出类AppComponent{
构造函数(){
}
}

诀窍是使用`使代码执行{{globals.var}

看看这种方法:

如果您可以在.ts文件中使用模板,并且可以执行类似操作(从该帖子复制),请执行以下操作:

创建全局类:

export class Globals {
    isLoggedIn = true;
}
然后使用此组件:

import { Globals } from './globals';

@Component({
    selector: 'my-app',
    template: `<h1>My Component {{globals.isLoggedIn}}<h1/>`
})
export class AppComponent {
    constructor(){
    }
}
从“/Globals”导入{Globals};
@组成部分({
选择器:“我的应用程序”,
模板:`My Component{{globals.isLoggedIn}`
})
导出类AppComponent{
构造函数(){
}
}

诀窍是使用`使此代码执行{{globals.var}

您可以
管道
一个随机值来返回一个
布尔值
,具体取决于全局变量

<div #app>
    <div *ngIf="'randomstring' | auth">...</div>
</div>

...
auth
在这种情况下指的是一个
AuthPipe
,它返回全局变量
true
false

现在只需在管道中注入依赖项


这是一个肮脏的修复程序,但它应该可以工作,因为可以在模板中访问
pipe

您可以
pipe
一个随机值来返回一个
布尔值,具体取决于全局变量

<div #app>
    <div *ngIf="'randomstring' | auth">...</div>
</div>

...
auth
在这种情况下指的是一个
AuthPipe
,它返回全局变量
true
false

现在只需在管道中注入依赖项


这是一个肮脏的修复程序,但它应该可以工作,因为
管道可以在模板中访问

我只能看到两种方法来做到这一点,但这两种方法都涉及在需要它的组件中注入公共服务。 您可以做一些事情来确保不必在构造函数和模板之外更新组件代码

选项-模板直接调用服务 应用程序.component.ts

import {SecurityService} from './security.service';
@Component({
    selector: '[App]',
    template: `<div *ngIf="securityService.isLoggedIn">Logged in!</div>`
})
export class ApplicationComponent {
  constructor(public securityService: SecurityService){ }
}
import {SecurityService} from './security.service';
export abstract class SecurityContextComponent {
  constructor(protected securityService: SecurityService){}

  get isLoggedIn(): boolean{
    return this.securityService.isLoggedIn;
  }
}
import {SecurityContextComponent} from './security-context.component';
import {SecurityService} from './security.service';

@Component({
    selector: '[App]',
    template: `<div *ngIf="isLoggedIn">Logged in!</div>`
})
export class ApplicationComponent implements SecurityContextComponent {
  constructor(securityService: SecurityService){
    super(securityService);
  }
}
应用程序.component.ts

import {SecurityService} from './security.service';
@Component({
    selector: '[App]',
    template: `<div *ngIf="securityService.isLoggedIn">Logged in!</div>`
})
export class ApplicationComponent {
  constructor(public securityService: SecurityService){ }
}
import {SecurityService} from './security.service';
export abstract class SecurityContextComponent {
  constructor(protected securityService: SecurityService){}

  get isLoggedIn(): boolean{
    return this.securityService.isLoggedIn;
  }
}
import {SecurityContextComponent} from './security-context.component';
import {SecurityService} from './security.service';

@Component({
    selector: '[App]',
    template: `<div *ngIf="isLoggedIn">Logged in!</div>`
})
export class ApplicationComponent implements SecurityContextComponent {
  constructor(securityService: SecurityService){
    super(securityService);
  }
}
从'./security context.component'导入{SecurityContextComponent};
从“./security.service”导入{SecurityService};
@组成部分({
选择器:“[App]”,
模板:`登录`
})
导出类ApplicationComponent实现SecurityContextComponent{
构造函数(securityService:securityService){
超级(保安服务);;
}
}

我只能看到两种方法,但这两种方法都涉及在需要公共服务的组件中注入公共服务。 您可以做一些事情来确保不必在构造函数和模板之外更新组件代码

选项-模板直接调用服务 应用程序.component.ts

import {SecurityService} from './security.service';
@Component({
    selector: '[App]',
    template: `<div *ngIf="securityService.isLoggedIn">Logged in!</div>`
})
export class ApplicationComponent {
  constructor(public securityService: SecurityService){ }
}
import {SecurityService} from './security.service';
export abstract class SecurityContextComponent {
  constructor(protected securityService: SecurityService){}

  get isLoggedIn(): boolean{
    return this.securityService.isLoggedIn;
  }
}
import {SecurityContextComponent} from './security-context.component';
import {SecurityService} from './security.service';

@Component({
    selector: '[App]',
    template: `<div *ngIf="isLoggedIn">Logged in!</div>`
})
export class ApplicationComponent implements SecurityContextComponent {
  constructor(securityService: SecurityService){
    super(securityService);
  }
}
应用程序.component.ts

import {SecurityService} from './security.service';
@Component({
    selector: '[App]',
    template: `<div *ngIf="securityService.isLoggedIn">Logged in!</div>`
})
export class ApplicationComponent {
  constructor(public securityService: SecurityService){ }
}
import {SecurityService} from './security.service';
export abstract class SecurityContextComponent {
  constructor(protected securityService: SecurityService){}

  get isLoggedIn(): boolean{
    return this.securityService.isLoggedIn;
  }
}
import {SecurityContextComponent} from './security-context.component';
import {SecurityService} from './security.service';

@Component({
    selector: '[App]',
    template: `<div *ngIf="isLoggedIn">Logged in!</div>`
})
export class ApplicationComponent implements SecurityContextComponent {
  constructor(securityService: SecurityService){
    super(securityService);
  }
}
从'./security context.component'导入{SecurityContextComponent};
从“./security.service”导入{SecurityService};
@组成部分({
选择器:“[App]”,
模板:`登录`
})
导出类ApplicationComponent实现SecurityContextComponent{
构造函数(securityService:securityService){
超级(保安服务);;
}
}

使用指令而不是ngIf怎么样?这样,您只需将服务注入指令中,在组件中使用时,它也很好、很干,并且标记量很小

差不多

@Directive({
  selector: '[showIfLoggedIn]'
})
export class ShowIfLoggedInDirective implements OnInit {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainerRef: ViewContainerRef
  ) { }

  ngOnInit() {
    var isLoggedIn = false;//TODO use service here and inject into constructor.
    if( isLoggedIn ) {
        this.viewContainerRef.createEmbeddedView(this.templateRef);
      } else {
        this.viewContainerRef.clear();
      }
  }
}
然后

红色(如果已登录)

使用指令而不是ngIf怎么样?这样,您只需将服务注入指令中,在组件中使用时,它也会很好、很干,并且标记量最小

差不多

@Directive({
  selector: '[showIfLoggedIn]'
})
export class ShowIfLoggedInDirective implements OnInit {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainerRef: ViewContainerRef
  ) { }

  ngOnInit() {
    var isLoggedIn = false;//TODO use service here and inject into constructor.
    if( isLoggedIn ) {
        this.viewContainerRef.createEmbeddedView(this.templateRef);
      } else {
        this.viewContainerRef.clear();
      }
  }
}
然后

红色(如果已登录)

听起来像是一场灾难。您实际上想要解决的是什么,或者您当前遇到的是什么问题,您必须为其创建服务并将其注入每个组件?我只需要一个全局
isLoggedIn
标志,而不必导入我的
AuthService
,并在每个组件中重复相同的代码。因此,我希望能够像
app.isLoggedIn
那样使用它,在指令中设置标志,我可以在任何需要它的组件中使用带有模板变量的指令。@Dhyey你能支持你的声明吗,或者你这么说是因为你不知道怎么做?我相信有一些奇怪的方法可以通过一个复杂的指令来实现这一点……对于您编写的大多数组件来说,登录和未登录状态都可用是常见的吗?如果不是的话,也许路由保护是一个更好的解决方案?@Igor你是对的,我确实在必要时使用路由保护,但这是专门用于向div添加特定类、隐藏/显示某些“哑”组件等。我只需要一个标志变量。我可以通过导入auth服务并调用
isLoggedIn()
方法来实现这一点,但我还是希望避免在每个组件中都这样做。您实际上想要解决的是什么,或者您当前遇到的是什么问题,您必须为其创建服务并将其注入每个组件?我只需要一个全局
isLoggedIn
标志,而不必导入我的
AuthService
,并在每个组件中重复相同的代码。所以我想成为一名