Angular绑定未更新

时间:2018-11-06 13:17:51

标签: html angular typescript

我目前正在学习Angular 2+,但在理解绑定的工作方式时遇到了麻烦。我已经在Google上搜索了大约半小时,但还没有找到我想念的东西。

我的页面上有一个简单的按钮,此按钮上的文本基于bool绑定到TypeScript中的属性。当我单击按钮时,它应该翻转布尔值,但是我的isTrackingText属性不会更改。

这是html中的我的按钮:

# => Strong string: Minumum number should be greater than 5 otherwise by default 8 character string.
require 'safe_random'
puts SafeRandom.strong_string                   # => 4skgSy93zaCUZZCoF9WiJF4z3IDCGk%Y
puts SafeRandom.strong_string(3)                # => P4eUbcK%
puts SafeRandom.strong_string(5)                # => 5$Rkdo

这是TypeScript中的bool和绑定文本属性

<button ion-button block (click)="startTracking()">{{ isTrackingText }}</button>

最后是实际的点击事件:

isTracking: boolean = false;
isTrackingText: string = (!this.isTracking ? "Start Tracking" : "Stop Tracking");

更新:对不起,我应该提到我知道我可以在按钮单击事件中对其进行更改,我的问题是更多如何通知isTrackingText它的后备字段已更改。

5 个答案:

答案 0 :(得分:2)

其他答案都显示了如何手动同步值,但是另一种选择是使用吸气剂代替适当的字段:

isTracking: boolean = false;

get isTrackingText(): string {
    return !this.isTracking ? "Start Tracking" : "Stop Tracking";
}

仍然可以从模板/其他代码中访问它,就好像它是一个字段一样(即,您不需要像函数一样调用它),并且模板将在运行更改检测时重新评估它。显然,与手动更新值相比,这样做的开销很小(我的意思是很少),但是便利因素可能值得这样做。

所有这些,如果只在一个地方使用此逻辑,我强烈考虑将其放在模板本身中,因为它纯粹是表示性的。就是我,:)

答案 1 :(得分:0)

此行:

isTrackingText: string = (!this.isTracking ? "Start Tracking" : "Stop Tracking");

只是声明变量isTrackingText并为其赋值(!this.isTracking ? "Start Tracking" : "Stop Tracking")

因此,在调用方法startTracking()时,仅更改了布尔值isTracking,要更新isTrackingText,您必须再次分配其值,因此代码将是:

startTracking() {
    console.log("Toggle Tracking!");
    this.isTracking = !this.isTracking;
    this.isTrackingText: string = (!this.isTracking ? "Start Tracking" : "Stop Tracking");
}

此致

答案 2 :(得分:0)

我认为您也必须更新isTrackingText变量。

startTracking() {
    console.log("Toggle Tracking!");
    this.isTracking = !this.isTracking;
    this.isTrackingText = !this.isTracking ? "Start Tracking" : "Stop Tracking";
}

答案 3 :(得分:0)

您不能“通知”有关更改后备布尔值的文本属性。 您可以执行以下任一操作:

  1. “拦截”布尔属性的设置并触发text属性的更新。
  2. 将text属性定义为“计算的”属性,该属性仅取决于布尔值。

这两种方法都使用打字稿的accessors功能

第一种方法如下:

private _isTracking: boolean;
get isTracking(){return this._isTracking;}
set isTracking(v: boolean){
  this._isTracking = v;
  this.trackingText = v ? ....; // your logic
}
isTrackingText: string;

constructor(){
  this.isTracking = false;
}

如您所见,这有点冗长。

第二种方法是更清洁的IMO:

isTracking = false;
get trackingText(){
  return this.isTracking ? ....; //your logic;
}

请注意,按照这种方法,每次“访问” trackingText成员时,都会重新计算该值。因此,如果计算是CPU密集型的,则不是最佳方法。

答案 4 :(得分:-1)

自从您启动Angular以来,@ Mohamed已经回答了该原理,让我为您解释一下反应式编程:

ReactiveX是实现Observable / Observer模式的库,具有一个称为RxJS的Javascript实现。 Angular在很多方面都使用它,从用户事件到HTTP调用。

根据您的情况,您可以创建一个观察者(您的文本),该监听器将监听 Observable (您的布尔值)上的更改。

首先导入正确的依赖项

import { Subject } from 'rxjs';

(主题是同时充当可观察者和观察者的代理)

接下来,您将创建一个新的Observable:

isTracking$ = new Subject();

constructor() {
  this.isTracking$.next(this.isTracking);
}

每次您调用.next时,都会发出一个新事件,使所有观察者做出反应。

由于您还没有,所以我们创建一个:

isTrackingText$ = this.isTracking;

现在,每次更改时,此观察者将被更新。

要在HTML中显示观察者值,请使用async管道:

<button ion-button block (click)="startTracking()">{{ isTrackingText$ | async }}</button>

您将看到它只显示一个布尔值:这是因为我们还没有给出文本逻辑。

我们将导入运营商来更改流的值:

import { map } from 'rxjs/operators';

有了这个,您现在可以在观察者中管道获取值:

isTrackingText$ = this.isTracking$.pipe(
  map(tracking => tracking ? 'Is tracking' : 'Is not tracking')
);

现在,您的按钮应该可以使用给定的文本了!最后修改,您的功能:

startTracking() {
  console.log("Toggle Tracking!");
  this.isTracking = !this.isTracking;
  this.isTracking$.next(this.isTracking);
}