Angular: only bootstrap the root application element (#40822)

* Angular: Do not bootstrap Angular against entire document

* Do not retrieve injector by using angular instance directly.
This commit is contained in:
Dominik Prokop 2021-10-29 11:31:41 +02:00 committed by GitHub
parent 67861c72d2
commit afdd9b2455
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 8 additions and 5 deletions

View File

@ -89,7 +89,7 @@ export class AppWrapper extends React.Component<AppWrapperProps, AppWrapperState
navigationLogger('AppWrapper', false, 'rendering'); navigationLogger('AppWrapper', false, 'rendering');
// @ts-ignore // @ts-ignore
const appSeed = `<grafana-app ng-cloak></app-notifications-list><div id="ngRoot"></div></grafana-app>`; const appSeed = `<grafana-app ng-cloak></app-notifications-list></grafana-app>`;
return ( return (
<Provider store={store}> <Provider store={store}>
@ -105,12 +105,15 @@ export class AppWrapper extends React.Component<AppWrapperProps, AppWrapperState
{pageBanners.map((Banner, index) => ( {pageBanners.map((Banner, index) => (
<Banner key={index.toString()} /> <Banner key={index.toString()} />
))} ))}
<div <div
id="ngRoot"
ref={this.container} ref={this.container}
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: appSeed, __html: appSeed,
}} }}
/> />
<AppNotificationList /> <AppNotificationList />
<SearchWrapper /> <SearchWrapper />
{this.state.ngInjector && this.container && this.renderRoutes()} {this.state.ngInjector && this.container && this.renderRoutes()}

View File

@ -104,7 +104,7 @@ export class AngularApp {
} }
bootstrap() { bootstrap() {
const injector = angular.bootstrap(document, this.ngModuleDependencies); const injector = angular.bootstrap(document.getElementById('ngRoot')!, this.ngModuleDependencies);
monkeyPatchInjectorWithPreAssignedBindings(injector); monkeyPatchInjectorWithPreAssignedBindings(injector);

View File

@ -1,13 +1,13 @@
import angular from 'angular';
import $ from 'jquery'; import $ from 'jquery';
import { partition, each } from 'lodash'; import { partition, each } from 'lodash';
//@ts-ignore //@ts-ignore
import Drop from 'tether-drop'; import Drop from 'tether-drop';
import { CreatePlotOverlay } from '@grafana/data'; import { CreatePlotOverlay } from '@grafana/data';
import { getLegacyAngularInjector } from '@grafana/runtime';
/** @ngInject */ /** @ngInject */
const createAnnotationToolip: CreatePlotOverlay = (element, event, plot) => { const createAnnotationToolip: CreatePlotOverlay = (element, event, plot) => {
const injector = angular.element(document).injector(); const injector = getLegacyAngularInjector();
const content = document.createElement('div'); const content = document.createElement('div');
content.innerHTML = '<annotation-tooltip event="event" on-edit="onEdit()"></annotation-tooltip>'; content.innerHTML = '<annotation-tooltip event="event" on-edit="onEdit()"></annotation-tooltip>';
@ -68,7 +68,7 @@ const createEditPopover: CreatePlotOverlay = (element, event, plot) => {
// wait for element to be attached and positioned // wait for element to be attached and positioned
setTimeout(() => { setTimeout(() => {
const injector = angular.element(document).injector(); const injector = getLegacyAngularInjector();
const content = document.createElement('div'); const content = document.createElement('div');
content.innerHTML = '<event-editor panel-ctrl="panelCtrl" event="event" close="close()"></event-editor>'; content.innerHTML = '<event-editor panel-ctrl="panelCtrl" event="event" close="close()"></event-editor>';