Revert "Do ModelView initialization actions before others (#11512)" (#11677)

This reverts commit 9bdd5f2899b36a44bca4add1f05164cf1489929b.
This commit is contained in:
Charles Gagnon
2020-08-06 08:47:33 -07:00
committed by GitHub
parent 9c67832880
commit 9bdfa57be6
3 changed files with 24 additions and 32 deletions

View File

@@ -67,9 +67,8 @@ export interface IModelStore {
* *
* @param componentId unique identifier of the component * @param componentId unique identifier of the component
* @param action some action to perform * @param action some action to perform
* @param isInitialization whether this is an initialization action that will run before other actions
*/ */
eventuallyRunOnComponent<T>(componentId: string, action: (component: IComponent) => T, isInitialization?: boolean): Promise<T>; eventuallyRunOnComponent<T>(componentId: string, action: (component: IComponent) => T): Promise<T>;
/** /**
* Register a callback that will validate components when given a component ID * Register a callback that will validate components when given a component ID
*/ */

View File

@@ -19,7 +19,6 @@ export class ModelStore implements IModelStore {
private _descriptorMappings: { [x: string]: IComponentDescriptor } = {}; private _descriptorMappings: { [x: string]: IComponentDescriptor } = {};
private _componentMappings: { [x: string]: IComponent } = {}; private _componentMappings: { [x: string]: IComponent } = {};
private _componentActions: { [x: string]: Deferred<IComponent> } = {}; private _componentActions: { [x: string]: Deferred<IComponent> } = {};
private _componentInitializationActions: { [x: string]: Deferred<IComponent> } = {};
private _validationCallbacks: ((componentId: string) => Thenable<boolean>)[] = []; private _validationCallbacks: ((componentId: string) => Thenable<boolean>)[] = [];
constructor() { constructor() {
} }
@@ -52,12 +51,12 @@ export class ModelStore implements IModelStore {
return this._componentMappings[componentId]; return this._componentMappings[componentId];
} }
eventuallyRunOnComponent<T>(componentId: string, action: (component: IComponent) => T, isInitialization: boolean = false): Promise<T> { eventuallyRunOnComponent<T>(componentId: string, action: (component: IComponent) => T): Promise<T> {
let component = this.getComponent(componentId); let component = this.getComponent(componentId);
if (component) { if (component) {
return Promise.resolve(action(component)); return Promise.resolve(action(component));
} else { } else {
return this.addPendingAction(componentId, action, isInitialization); return this.addPendingAction(componentId, action);
} }
} }
@@ -70,18 +69,13 @@ export class ModelStore implements IModelStore {
return Promise.all(this._validationCallbacks.map(callback => callback(componentId))).then(validations => validations.every(validation => validation === true)); return Promise.all(this._validationCallbacks.map(callback => callback(componentId))).then(validations => validations.every(validation => validation === true));
} }
private addPendingAction<T>(componentId: string, action: (component: IComponent) => T, isInitialization: boolean): Promise<T> { private addPendingAction<T>(componentId: string, action: (component: IComponent) => T): Promise<T> {
// We create a promise and chain it onto a tracking promise whose resolve method // We create a promise and chain it onto a tracking promise whose resolve method
// will only be called once the component is created // will only be called once the component is created
let deferredPromise = this._componentActions[componentId];
// If this is an initialization action we want to run it before the other actions that may have come in
// after initialization but before the component was finished being created or we hit race conditions with
// setting properties
const actionsStore = isInitialization ? this._componentInitializationActions : this._componentActions;
let deferredPromise = actionsStore[componentId];
if (!deferredPromise) { if (!deferredPromise) {
deferredPromise = new Deferred(); deferredPromise = new Deferred();
actionsStore[componentId] = deferredPromise; this._componentActions[componentId] = deferredPromise;
} }
let promise = deferredPromise.promise.then((component) => { let promise = deferredPromise.promise.then((component) => {
return action(component); return action(component);
@@ -90,10 +84,9 @@ export class ModelStore implements IModelStore {
} }
private runPendingActions(componentId: string, component: IComponent) { private runPendingActions(componentId: string, component: IComponent) {
// If we have initialization actions to run start those first let promiseTracker = this._componentActions[componentId];
const initializationActionsPromise = this._componentInitializationActions[componentId]; if (promiseTracker) {
initializationActionsPromise?.resolve(component); promiseTracker.resolve(component);
const actionsPromise = this._componentActions[componentId]; }
actionsPromise?.resolve(component);
} }
} }

View File

@@ -58,12 +58,12 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
throw new Error(nls.localize('componentTypeNotRegistered', "Could not find component for type {0}", ModelComponentTypes[component.type])); throw new Error(nls.localize('componentTypeNotRegistered', "Could not find component for type {0}", ModelComponentTypes[component.type]));
} }
let descriptor = this.modelStore.createComponentDescriptor(typeId, component.id); let descriptor = this.modelStore.createComponentDescriptor(typeId, component.id);
this.setProperties(component.id, component.properties, true); this.setProperties(component.id, component.properties);
this.setLayout(component.id, component.layout, true); this.setLayout(component.id, component.layout);
this.registerEvent(component.id, true); this.registerEvent(component.id);
if (component.itemConfigs) { if (component.itemConfigs) {
for (let item of component.itemConfigs) { for (let item of component.itemConfigs) {
this.addToContainer(component.id, item, undefined, true); this.addToContainer(component.id, item);
} }
} }
@@ -82,12 +82,12 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
this.queueAction(componentId, (component) => component.clearContainer()); this.queueAction(componentId, (component) => component.clearContainer());
} }
addToContainer(containerId: string, itemConfig: IItemConfig, index?: number, isInitialization?: boolean): void { addToContainer(containerId: string, itemConfig: IItemConfig, index?: number): void {
// Do not return the promise as this should be non-blocking // Do not return the promise as this should be non-blocking
this.queueAction(containerId, (component) => { this.queueAction(containerId, (component) => {
let childDescriptor = this.defineComponent(itemConfig.componentShape); let childDescriptor = this.defineComponent(itemConfig.componentShape);
component.addToContainer(childDescriptor, itemConfig.config, index); component.addToContainer(childDescriptor, itemConfig.config, index);
}, isInitialization); });
} }
removeFromContainer(containerId: string, itemConfig: IItemConfig): void { removeFromContainer(containerId: string, itemConfig: IItemConfig): void {
@@ -98,11 +98,11 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
}); });
} }
setLayout(componentId: string, layout: any, isInitialization?: boolean): void { setLayout(componentId: string, layout: any): void {
if (!layout) { if (!layout) {
return; return;
} }
this.queueAction(componentId, (component) => component.setLayout(layout), isInitialization); this.queueAction(componentId, (component) => component.setLayout(layout));
} }
setItemLayout(containerId: string, itemConfig: IItemConfig): void { setItemLayout(containerId: string, itemConfig: IItemConfig): void {
@@ -112,24 +112,24 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
}); });
} }
setProperties(componentId: string, properties: { [key: string]: any; }, isInitialization?: boolean): void { setProperties(componentId: string, properties: { [key: string]: any; }): void {
if (!properties) { if (!properties) {
return; return;
} }
this.queueAction(componentId, (component) => component.setProperties(properties), isInitialization); this.queueAction(componentId, (component) => component.setProperties(properties));
} }
refreshDataProvider(componentId: string, item: any): void { refreshDataProvider(componentId: string, item: any): void {
this.queueAction(componentId, (component) => component.refreshDataProvider(item)); this.queueAction(componentId, (component) => component.refreshDataProvider(item));
} }
private queueAction<T>(componentId: string, action: (component: IComponent) => T, isInitialization?: boolean): void { private queueAction<T>(componentId: string, action: (component: IComponent) => T): void {
this.modelStore.eventuallyRunOnComponent(componentId, action, isInitialization).catch(err => { this.modelStore.eventuallyRunOnComponent(componentId, action).catch(err => {
// TODO add error handling // TODO add error handling
}); });
} }
registerEvent(componentId: string, isInitialization?: boolean) { registerEvent(componentId: string) {
this.queueAction(componentId, (component) => { this.queueAction(componentId, (component) => {
this._register(component.registerEventHandler(e => { this._register(component.registerEventHandler(e => {
let modelViewEvent: IModelViewEventArgs = assign({ let modelViewEvent: IModelViewEventArgs = assign({
@@ -138,7 +138,7 @@ export abstract class ViewBase extends AngularDisposable implements IModelView {
}, e); }, e);
this._onEventEmitter.fire(modelViewEvent); this._onEventEmitter.fire(modelViewEvent);
})); }));
}, isInitialization); });
} }
public get onEvent(): Event<IModelViewEventArgs> { public get onEvent(): Event<IModelViewEventArgs> {