我如何动态导出变量 angular

How do i dynamically export variable angular

我正在尝试将 x 以每半秒增加一的方式导出到 HTML。但看起来它只是在构建时导出。我已经尝试过注入和 ngOnChangesngDoCheck,但很可能我做错了什么我只用 angular 编程了大约一个星期。

landing.component.ts

    import { Component, OnInit} from '@angular/core';
    
    var printTime = window.setInterval(increaseX, 500);
    var x = 0;
    
    function increaseX() {
      x++;
    }
    
    @Component({
      selector: 'app-landing',
      templateUrl: './landing.component.html',
      styleUrls: ['./landing.component.css']
    })
    
    export class LandingComponent{
      x = x;
    }

landing.component.html

    <div class="landingText">
        <p>I Love<br>&lt;{{x}}/&gt;</p>
    </div>

Rusulting Website

尝试使用BehaviorSubject

 @Component({
  selector: 'app-root',
  template: '<p>{{this.$subject|async}}</p>'
 })
 export class AppComponent implements OnInit {
   $subject: BehaviorSubject<number> = new BehaviorSubject<number>(1);

   ngOnInit(): void {
    window.setInterval(() => this.$subject.next(this.$subject.value + 1), 500);
   }
 }

这也行。

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-landing',
  templateUrl: './landing.component.html',
  styleUrls: ['./landing.component.css']
})

export class LandingComponent implements OnInit  {
  x: number = 0;

  constructor() {}

  ngOnInit() {
    const self = this;
    setInterval(() => ++self.x, 500);
  }  
}

它不起作用的原因是因为 x 是一个原始值。所以当你做 x = x 时,你只分配了一次。当您在 class 之外更改它时,这不会更新在 class 上创建的原始字段。无论如何,不​​建议在 classes 之外做事,就像你在那里做的那样。

解决方案完全取决于您想要什么。我个人认为你最好在这里使用服务。这会将任何逻辑与组件分离并将其委托给服务:

@Injectable({
  providedIn: 'root'
})
export class XService {
  x = 0;

  constructor() {
    window.setInterval(() => increaseX(), 500);
  }

  private increaseX(): void {
    this.x++;
  }
}

然后您可以在您的组件中访问这个值:

export class LandingComponent{
  constructor(readonly xs: XService) {}
}

并将其显示在您的模板中:

<div class="landingText">
  <p>I Love<br>&lt;{{xs.x}}/&gt;</p>
</div>

但是,如果您使用 OnPush 更改检测策略,这将不起作用,这是推荐使用的方法。你甚至可以让它变得很酷,并为此使用带有 async 管道的 Observable 模式,它看起来像这样:

@Injectable({
  providedIn: 'root'
})
export class XService {
  readonly x$ = interval(500);
}

和您的模板

<div class="landingText">
  <p>I Love<br>&lt;{{xs.x$ | async}}/&gt;</p>
</div>

这将在 OnPush 变化检测中存活下来。

我已经为这个解决方案创建了一个stackblitz


但是,如果您只是想快速解决问题,您只需真正更改原始代码中的一件事,那就是将 x 设置为 getter 在您的组件上:

@Component({
  selector: 'app-landing',
  templateUrl: './landing.component.html',
  styleUrls: ['./landing.component.css']
})

export class LandingComponent{
  get x() { return x; }
}

这将始终获得 x 的更新值。不过,这不是 OnPush 'worthy'