diff --git a/public/app/core/components/grafana_app.ts b/public/app/core/components/grafana_app.ts index 4272c8a0b71..2774ab99426 100644 --- a/public/app/core/components/grafana_app.ts +++ b/public/app/core/components/grafana_app.ts @@ -10,6 +10,7 @@ import colors from 'app/core/utils/colors'; import { BackendSrv, setBackendSrv } from 'app/core/services/backend_srv'; import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; import { configureStore } from 'app/store/configureStore'; +import { AngularLoader, setAngularLoader } from 'app/core/services/AngularLoader'; export class GrafanaCtrl { /** @ngInject */ @@ -22,11 +23,13 @@ export class GrafanaCtrl { contextSrv, bridgeSrv, backendSrv: BackendSrv, - datasourceSrv: DatasourceSrv + datasourceSrv: DatasourceSrv, + angularLoader: AngularLoader ) { // sets singleston instances for angular services so react components can access them - configureStore(); + setAngularLoader(angularLoader); setBackendSrv(backendSrv); + configureStore(); $scope.init = () => { $scope.contextSrv = contextSrv; diff --git a/public/app/core/services/AngularLoader.ts b/public/app/core/services/AngularLoader.ts new file mode 100644 index 00000000000..e3a7dec4351 --- /dev/null +++ b/public/app/core/services/AngularLoader.ts @@ -0,0 +1,42 @@ +import angular from 'angular'; +import coreModule from 'app/core/core_module'; +import _ from 'lodash'; + +export interface AngularComponent { + destroy(); +} + +export class AngularLoader { + /** @ngInject */ + constructor(private $compile, private $rootScope) {} + + load(elem, scopeProps, template): AngularComponent { + const scope = this.$rootScope.$new(); + + _.assign(scope, scopeProps); + + const compiledElem = this.$compile(template)(scope); + const rootNode = angular.element(elem); + rootNode.append(compiledElem); + + return { + destroy: () => { + scope.$destroy(); + compiledElem.remove(); + }, + }; + } +} + +coreModule.service('angularLoader', AngularLoader); + +let angularLoaderInstance: AngularLoader; + +export function setAngularLoader(pl: AngularLoader) { + angularLoaderInstance = pl; +} + +// away to access it from react +export function getAngularLoader(): AngularLoader { + return angularLoaderInstance; +}