简体   繁体   中英

How to share typescript classe between classic HTML5 and Angular2 apps?

We have some legacy regular HTML5 apps that use our own dataviz module (javascript lib based on d3.js).

We started a new app written in typescript on angluar2 which also need to include the same dataviz component.

I have rewritten the dataviz module as a brand new lib in typescript based on react that nicely fits in the angular2 app. I have taken the rewrite opportunity to better architecture the dataviz module by better centralising generic code and make the web service an angular service based on a new web service typescript class.

The issue I am facing now is that I have the same dataviz module written in two different langages (and tech support) and this situation oblige us to maintain two different sources codes.

In other words, is it possible to inject the typescript version into the legacy HTML5/javascript app?

So far, I imagine I can include the typescript langage straight into the legacy app by using the javascript angular2 has generated.

But how can I address the angular2 decoration command such as @Injectable, @Component, @ViewChild etC. and the imports?

For instance, when I include the js generated file of the following typescript, I got the error TypeError: undefined is not an object (evaluating 'core_1.ViewChild') which appears here :

   }; // drawChartTraffic(force)
    __decorate([
        core_1.ViewChild('chart'), 
        __metadata('design:type', core_1.ElementRef)
    ], DatavizComponent.prototype, "chartContainer", void 0);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', String)
    ], DatavizComponent.prototype, "graphId", void 0);

My understanding is that I should include angular2/core and all used libs, which makes no sense because what I want to achieve is simplicity…

Should I turn to iframe inclusion of the Dataviz? Any idea?

The typescript excerpt:

import { Component, OnInit, OnChanges, ViewChild, ElementRef, Input, ViewEncapsulation } from '@angular/core';
import * as d3 from 'd3';
import { Observable }           from 'rxjs/Observable';
import { ZEENSMetricsService }  from './zeensmetrics.service'


@Component({
    selector:    'dataviz-offers-volumes',
    templateUrl: 'app/dataviz.component.html',
    styleUrls:  ['app/dataviz.component.css'],
    encapsulation: ViewEncapsulation.None,
    providers: [
        {provide: 'wsAuthKey',  useValue: 'abc'}, 
        {provide: 'wsHost',     useValue: 'efg'}, 
    ],
})
export class DatavizComponent implements OnInit, OnChanges {

    @ViewChild('chart') private chartContainer: ElementRef;
    @Input() private graphId:string;
    @Input() private wsAuthKey:string;
    @Input() private wsHost:string;
    @Input() private maxSamples=12;

    private graph: any;     // chartContainer native element

    // …
}

Since your DatavizComponent is a Angular 2 component, you cannot include it in a legacy app without including the whole Angular 2 framework.

So, I think you should split your core Dataviz module as a framework-agnostic library. Put in this lib all the code that is not dependent on Angular. Import this library and encapsulate it in your Angular component.

import {template, styles, Dataviz} from 'my-dataviz-lib';

@Component({
    selector: 'dataviz-offers-volumes',
    template: template,
    styles: styles,
    //...
})
export class DatavizComponent implements OnInit, OnChanges {

    private viz: Dataviz; // Your library object

    // …
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM