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

时间:2017-11-07 14:30:13

标签: angular typescript

我想创建一个可以使用模板变量的指令,这样我就可以访问一个全局变量,类似于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>

这样的事情可能吗?

4 个答案:

答案 0 :(得分:5)

使用指令而不是ngIf怎么样,这样你只需要将你的服务注入到指令中,在你的组件中使用时,它也很好,DRY和最小化标记。

这样的东西
@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();
      }
  }
}

然后使用

<h2 *showIfLoggedIn> I am logged in </h2>

并切换课程

@Directive({
  selector : '[applyClassIfLoggedIn]'
})

export class ApplyClassIfLoggedIn implements OnInit {
  @Input('applyClassIfLoggedIn') className;
  constructor(
    private ele: ElementRef,
    private renderer: Renderer2
  ) { }


  ngOnInit() {
    var isLoggedIn = true;//TODO use service here.
    if( isLoggedIn ) {
        this.renderer.addClass(this.ele.nativeElement, this.className);
    }

  }
}

然后

<h2 applyClassIfLoggedIn='logged-in'>Red if logged in </h2>

Plunkr here

答案 1 :(得分:2)

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

选项 - 模板直接调用服务

<强> application.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){ }
}

选项 - 共享抽象类

安全-context.component.ts

import {SecurityService} from './security.service';
export abstract class SecurityContextComponent {
  constructor(protected securityService: SecurityService){}

  get isLoggedIn(): boolean{
    return this.securityService.isLoggedIn;
  }
}

<强> application.component.ts

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

答案 2 :(得分:1)

您可以pipe随机值返回boolean,具体取决于全局变量。

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

auth在这种情况下引用AuthPipe,它返回全局变量truefalse

现在你只需要在管道中注入一个依赖项?

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

答案 3 :(得分:0)

看看这种方法:

https://stackoverflow.com/a/39946948/222328

如果您可以在.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.var}}