簡體   English   中英

Angular中的訂閱無法使用兩種方式進行數據綁定嗎?

[英]Two way data binding not working from subscribe in Angular?

我正在訂閱Angular中的一個主題,涉及值更改,我試圖更改組件中的變量值。 在控制台中,該值顯示更新,但在視圖(HTML)上不顯示。

Service.ts

    export class GMapsService {
  public mysubject: Subject<any> = new Subject();

  getData(or, des) {
    var origin1 = or;
    var destinationA = des;
    var service = new google.maps.DistanceMatrixService();
    var self = this;

    service.getDistanceMatrix(
      {
        origins: [origin1],
        destinations: [destinationA],
        travelMode: 'DRIVING',
        avoidHighways: false,
        avoidTolls: true,
      },
      (response, status) => {
        // this.mysubject.next(response);

        setInterval(
          function () {
            self.mysubject.next(Math.random())
          },
          2000
        )
      }
    );


  }
}

app.component.ts

    export class AppComponent implements OnInit {
  title: any = 'app';

  constructor(private GMapsService: GMapsService) { }

  ngOnInit() {
    this.GMapsService.getData('dallas, tx', 'austin, tx');

    this.GMapsService.mysubject.subscribe((value) => {
      this.title = value;
      console.log(this.title);       
 //title is random number in console. ex: 0.4333333
 //title is still 'app' on view till now.
    });

setTimeout(() => {
      console.log(this.title);
    }, 5000);


//title is random number in console.  ex: 0.4333333
// title suddenly become 'random number  ex: 0.4333333' on view after it is logged after 5 secs. How does logging 'title' again after 5 seconds change its value?
  }
}

app.component.html

{{title}}

我相信,如果在控制台中更改相同的值,則它也應該反映在視圖部分。 在其他問題上,它表示我缺少此上下文,但是控制台中的值正在更新,因此我相信我沒有丟失該上下文。

編輯 :5秒鍾后,我嘗試記錄標題,它突然在視圖上更改。 僅記錄值如何在視圖上更改它?

由於您使用的是基本主題,因此您需要先訂閱主題,然后才能從同步調用中接收數據(除非對它進行模擬,否則getDistanceMatrix不應如此)。 也就是說,因為默認情況下基本主題不會重播上次發布的值。

如果要避免這種情況,可以使用ReplaySubject或BehaviorSubject:

service.ts

@Injectable()
export class GMapsService {
  public mysubject: ReplaySubject<any> = new ReplaySubject(1);

  getData(or, des) {
    var origin1 = or;
    var destinationA = des;
    var service = new google.maps.DistanceMatrixService();

    service.getDistanceMatrix(
      {
        origins: [origin1],
        destinations: [destinationA],
        travelMode: 'DRIVING',
        avoidHighways: false,
        avoidTolls: true,
      },
      (response, status) => {
        console.log('service callback');
        this.mysubject.next(response);
      }
    );
  }
}

component.ts

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  title: any = 'app';

  constructor(private GMapsService: GMapsService, private changeDetectorRef: ChangeDetectorRef) { }

  ngOnInit() {
    this.GMapsService.getData('dallas, tx', 'austin, tx');

    this.GMapsService.mysubject.subscribe((value) => {
      this.title = value;
      this.changeDetectorRef.detectChanges();
    });
  }
}

這里的工作示例

編輯:顯然,google DistanceMatrixService.getDistanceMatrix響應不會觸發更改檢測。 嘗試使用ChangeDetectorRef並手動查找更改。 我相應地更改了代碼示例。

附錄:Angular使用變更檢測系統,該系統掛接到異步事件的典型觸發器中,以檢測必須更新視圖的哪些部分。 觸發器的示例是用戶輸入,計時器(setTimeout,setInterval)或Websocket事件。 如果Google DistanceMatrixService使用一種方法來檢索不會觸發angular的變化檢測系統的數據,則不會檢查視圖數據是否發生變化,因此無法正確更新。 由於setTimeout觸發更改檢測,因此在使用setTimeout時它可以工作。 您可以在此處閱讀有關角度變化檢測系統的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM