10

我只是将此处找到的嵌入脚本 ( https://www.tradingview.com/widget/advanced-chart/ ) 中的函数复制到我的 Angular 5 应用程序中的一个组件中,并将源脚本包含在 angular-cli.json 中。但是,该组件返回错误“找不到名称 'TradingView'”。有人有什么建议吗?

4

6 回答 6

8

我找到了一种通过TradingView在组件中声明来解决编译错误的方法:

declare const TradingView: any;

export class ChartComponent implements AfterViewInit {
ngAfterViewInit() {
   new TradingView.widget({
      'container_id': 'technical-analysis',
      'autosize': true,
      'symbol': this.symbolPair,
      'interval': '120',
      'timezone': 'exchange',
      'theme': 'Dark',
      'style': '1',
      'toolbar_bg': '#f1f3f6',
      'withdateranges': true,
      'hide_side_toolbar': false,
      'allow_symbol_change': true,
      'save_image': false,
      'hideideas': true,
      'studies': [ 
      'MASimple@tv-basicstudies' ],
      'show_popup_button': true,
      'popup_width': '1000',
      'popup_height': '650'
    });
  }
}

看法:

<div id="technical-analysis"></div>
于 2018-01-17T13:30:56.847 回答
3

我知道这有点老了,但我现在只是在试用 TradingView 的小部件。这有很大帮助。结果是 TradingView 正在改变他们的小部件脚本的加载方式,我想我可能会分享我想出如何为他们的新旧加载方法制作可重用组件的方式。享受:

这是注入的版本(较新):

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

 @Component( {
   selector: 'rip-trading-view-fundamentals',
   template: `
       <div class="tradingview-widget-container" style="height: 300px;" #containerDiv>
           <div class="tradingview-widget-container__widget"></div>

       </div>
   `,
 } )

 export class TradingViewFundamentalsComponent implements AfterViewInit {

   // allows for loading with any symbol
   @Input() symbol: string = '';
   settings: any = {};
   // id for being able to check for errors using postMessage
   widgetId: string = '';

   // wanted to be able to hide the widget if the symbol passed in was invalid (don't love their sad cloud face)
   @ViewChild( 'containerDiv', { static: false } ) containerDiv: ElementRef;

   constructor( private _elRef: ElementRef ) {
   }

   ngAfterViewInit() {
     // need to do this in AfterViewInit because of the Input
     setTimeout( () => {
       this.widgetId = `${ this.symbol }_fundamnetals`;

       // postMessage listener for handling errors
       if ( window.addEventListener ) {
         window.addEventListener( 'message', ( e: any ) => {
             if ( e && e.data ) {
               console.log( e );
               const payload = e.data;
               // if the frameElementId is from this component, the symbol was no good and we should hide the widget
               if ( payload.name === 'tv-widget-no-data' && payload.frameElementId === this.widgetId ) {
                 this.containerDiv.nativeElement.style.display = 'none';
               }
             }
           },
           false,
         );
       }


       this.settings = {
         symbol: this.symbol,
         colorTheme: 'light',
         isTransparent: false,
         largeChartUrl: '',
         displayMode: 'regular',
         height: 300,
         autosize: true,
         locale: 'en',
       };
       const script = document.createElement( 'script' );
       script.src = 'https://s3.tradingview.com/external-embedding/embed-widget-financials.js';
       script.async = true;
       script.id = this.widgetId;
       script.innerHTML = JSON.stringify( this.settings );
       this.containerDiv.nativeElement.appendChild( script );
       const brandingDiv = document.createElement( 'div' );
       brandingDiv.innerHTML = `
     <div class="tradingview-widget-copyright">
     <a href="https://www.tradingview.com/symbols/${ this.symbol }/" rel="noopener" target="_blank">
     <span class="blue-text">${ this.symbol } Fundamental Data</span></a>
               by TradingView
           </div>
 `;

     } );
   }

 }

这是旧版本,通过使用全局 TradingView 对象在 index.html 中加载他们的库:

import { AfterViewInit, Component, ElementRef, HostListener, Input, ViewChild } from '@angular/core';
import { Logger } from '../../helpers/logger.service';

// declaration so Typescript knows about the TradingView object loaded in from index.html
declare const TradingView: any;

@Component( {
  selector: 'rip-trading-view-symbol-overview',
  template: `
      <div #containerDiv id="overview_{{symbol}}" class="tradingview-widget-container" style="height: 300px;"></div>
  `,
} )

export class TradingViewSymbolOverviewComponent implements AfterViewInit {

  chart: any;
  // allows for loading with any symbol and description
  @Input() symbol: string = '';
  @Input() description: string = '';
  // id for being able to check for errors using postMessage
  widgetId: string = '';

  // wanted to be able to hide the widget if the symbol passed in was invalid (don't love their sad cloud face)
  @ViewChild( 'containerDiv', { static: false } ) containerDiv: ElementRef;

  ngAfterViewInit() {
    // need to do this in AfterViewInit because of the Input
    setTimeout( () => {
      this.widgetId = `overview_${ this.symbol }`;

      // postMessage listener for handling errors
      if ( window.addEventListener ) {
        window.addEventListener( 'message', ( e: any ) => {
            if ( e && e.data ) {
              console.log( e );
              const payload = e.data;
              if (
                // if the frameElementId is from this component, the symbol was no good and we should hide the widget
                payload.name === 'tv-widget-no-data' && payload.frameElementId === this.widgetId ) {
                // console.log( 'No data available for the symbol profile widget' );
                this.containerDiv.nativeElement.style.display = 'none';
              }
            }
          },
          false,
        );
      }


      this.chart = new TradingView.MediumWidget( {
        container_id: this.widgetId,
        symbols: [
          [
            this.description,
            this.symbol,
          ],
          // could load more symbols, but we just needed the one at a time for now
          // [
          //   'Google',
          //   'GOOGL',
          // ],
          // [
          //   'Microsoft',
          //   'MSFT',
          // ],
        ],
        id: this.widgetId,
        chartOnly: false,
        // 'width': 1000,
        height: 300,
        autosize: true,
        locale: 'en',
        colorTheme: 'light',
        gridLineColor: '#F0F3FA',
        trendLineColor: '#1b66ae',
        fontColor: '#787B86',
        underLineColor: 'rgba(145,196,242,0.35)',
        isTransparent: false,
      } );
    } );
  }

}

如果有人有关于如何进一步改进的说明,我会全神贯注,我希望这些解决方案可以帮助任何寻找答案的人,因为那里没有很多答案,虽然 TradingView 似乎可以很快回复电子邮件,但他们没有我可以在他们的网站上找到的任何文档以寻求此类帮助。

于 2020-04-30T15:37:34.553 回答
2
  1. 之后,我将小部件加载脚本添加到 index.html
  2. 在组件的模板文件(html)中,我只留下了 html 标签
  3. 在组件的 ts 文件中:

    declare const TradingView: any;

    ngAfterViewInit()new TradingView.widget(...)把里面setTimeout

就是这样!有用。

于 2019-06-12T16:29:39.383 回答
2

只需添加

<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script> 

在 index.html 中,它将完美地工作。

于 2019-09-25T07:04:56.417 回答
0

适用于我的实现 https://stackblitz.com/edit/stack-48296351

于 2018-01-17T08:22:36.353 回答
-2

伙计们!其他解决方案如果您需要这些图表(例如在我的情况下),您可以使用例如 Flask 为您的应用程序创建一个简单的后端:

index.htmlinit.py (app/ init .py)中创建(app/templates/index.html),其中包含小部件代码:

from flask import Flask, request, render_template
from flask_restful import Resource, Api
from flask_cors import CORS, cross_origin

app = Flask(__name__)
app.config['DEBUG'] = True
CORS(app)

@app.route('/tradingView')
def getChart():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(port=6200)

然后开始运行服务器

在您的组件中添加:

<iframe src="http://127.0.0.1:6200/tradingView" frameborder="0"></iframe>

此解决方案需要 python 和烧瓶知识,但它尽可能简单,祝你好运!

于 2020-07-01T20:54:14.340 回答