Как остановить рендеринг нескольких таблиц после каждого обновления? - PullRequest
0 голосов
/ 18 июня 2020

У меня есть код angular, который использует виджет TradingView кросс-курсов валют. Теперь я предоставил пользователю список флажков для добавления и удаления валют из таблицы. Но всякий раз, когда я обновляю список валют, мне нужно вызывать функцию, которая отображает виджет. Проблема в том, что он создает новый виджет, и я не могу удалить предыдущий виджет. Итак, на экране отображается несколько виджетов. Я хочу удалить предыдущий виджет и оставить новый на своем месте. Это файл typscript:

import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core';
import { Router } from "@angular/router";

@Component({
  selector: 'app-forex-cross-rates',
  templateUrl: './forex-cross-rates.component.html',
  styleUrls: ['./forex-cross-rates.component.css']
})
export class ForexCrossRatesComponent implements AfterViewInit {

  symbol: string = "forex-cross-rates";
  settings: any = {};
  widgetId: string = '';
  counter = 0;

  public currencies = [
    "EUR","USD","JPY","GBP","CHF","AUD","CAD","NZD","CNY",
    "TRY","SEK","NOK","DKK","ZAR","HKD","SGD","THB","MXN",
    "IDR","KRW","PLN","ISK","KWD","PHP","MYR","INR","TWD",
    "SAR","RUB","ILS"
  ] ;

  public user_currencies = [
    "EUR","USD","JPY","GBP","CHF","AUD","CAD","NZD","CNY","INR"
  ]

  @ViewChild('containerDiv', {static: true}) containerDiv: ElementRef;

  constructor( private _elRef: ElementRef, private router: Router ) {
  }

  forexCrossRates(user_currencies) {
    setTimeout(() => {
      this.widgetId = `${ this.symbol }_fundamentals`;

      if (window.addEventListener) {
        window.addEventListener( 'message', ( e: any ) => {
          if( e && e.data ) {
            console.log(e);
            const payload = e.data;

            if (payload.name === 'tv-widget-no-data' && payload.frameElementId === this.widgetId) {
              this.containerDiv.nativeElement.style.display = 'none';
              }
            }
          }, false,
        );
      }
      this.settings = {
        "width": 840,
        "height": 400,
        "currencies": this.user_currencies,
        "isTransparent:": true,
        "colorTheme": "dark",
        "locale": "in",
        "largeChartUrl": "http://localhost:4200/forexcrossrates"
      };

      const script = document.createElement( 'script' );
      script.src = 'https://s3.tradingview.com/external-embedding/embed-widget-forex-cross-rates.js';
      script.async = true;
      script.id = this.widgetId;
      script.innerHTML = JSON.stringify( this.settings );
      this.containerDiv.nativeElement.appendChild( script );
      const brandingDiv = document.createElement( 'div' );
    } );
  }

  ngAfterViewInit() {
    this.forexCrossRates(this.user_currencies)
    console.log(this.containerDiv)
}

//Function that adds and removes elements from currencies list:
  AddCurrency(currency) {
    console.log(currency)
    if(this.user_currencies.includes(currency)) {
      var index = this.user_currencies.indexOf(currency);
      this.user_currencies.splice(index, 1);
      console.log("Removed:"+currency);
      console.log("Updated watchlist:"+this.user_currencies);
    }
    else {
      this.user_currencies.push(currency);
      console.log("Pushed:"+currency);
      console.log("Updated watchlist:"+this.user_currencies);
    }
    this.forexCrossRates(this.user_currencies)
    console.log("AddCurrency")
    console.log(this.containerDiv)
  }
}

А это html:

<div class="heading">
<hr>
<h1 style="padding-left: 20px;">Forex Cross Rates</h1>
<hr>
<br>
<table>
  <tr>
    <th>Currency</th>
  </tr>
  <tr *ngFor="let currency of currencies">
    <td *ngIf="user_currencies.includes(currency)"><input class="btn" type="checkbox" checked (click)="AddCurrency(currency)">{{currency}}</td>
    <td *ngIf="!user_currencies.includes(currency)"><input class="btn" type="checkbox" (click)="AddCurrency(currency)">{{currency}}</td>
  </tr>
</table>
<div class="tradingview-widget-container" style="height: 300px;   margin-left: auto;
  margin-right: auto;" #containerDiv>
  <div class="tradingview-widget-container__widget"></div>
</div>
</div>

Скриншот проблемы: enter image description here

1 Ответ

2 голосов
/ 18 июня 2020

Итак, вам нужно использовать либо elementref, либо средство визуализации, чтобы удалить тег скрипта из div перед повторным запуском функции, которая снова добавляет тег скрипта. Попробуйте добавить эту функцию в свой компонент:

  removeForexScriptTag() {
    const forexChartScript = this._elRef.nativeElement.querySelector(`#${this.widgetId}`);
    console.log(forexChartScript);
    forexChartScript.remove();
  }

затем добавьте к нему вызов прямо перед вызовом this.forexCrossRates () внутри вашей функции addCurrency (). Также обратите внимание на идентификатор, используемый в вызове querySelector (). Вам не нужен символ для этого виджета, и вам нужен только один за раз, поэтому вам не нужно, чтобы он был динамическим c. Вы можете просто установить this.widgetId на что-нибудь простое в верхней части компонента, например «forex-chart». Это изменение должно удалить тег скрипта, который удалит диаграмму, а затем снова добавит ее в новый список валют.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...