The approach for loading data in propertypane is to leverage OnInit function to load initial data for the control. since OnInit return a Promise, you can do the following:
protected onInit<T>(): Promise<void> {
return new Promise<void>((resolve, reject) => {
this._listService.getListsInfo()
.then((response: ISPListInfo[]) => {
this._dropdownListOptions = response.map((list: ISPListInfo) => {
return {
key: list.listTitle,
text: list.listTitle
};
});
resolve();
});
});
}
If you have multiple controls and those controls have dependency based on the each other, you can load the second control's data in onPropertyChanged method like the following:
protected onPropertyChanged(propertyPath: string, oldValue: any, newValue: any): void {
if (propertyPath === "selListTitle") {
this._listService.getListFieldsInfo(this.properties.selListTitle)
.then((response: ISPListFieldInfo[]) => {
this._dropdownXFieldOptions = response.map((field: ISPListFieldInfo) => {
return {
key: field.fieldTitle,
text: field.fieldTitle
};
});
this._dropdownYFieldOptions = response.map((field: ISPListFieldInfo) => {
return {
key: field.fieldTitle,
text: field.fieldTitle
};
});
//force the property panel to refresh
this.configureStart(true);
});
}
there are couple tricks here. First you need to check the propertyPath for the control you are listening and load your data. Second, once you have data loaded from your service, you need to call this.configureStart(true) to refresh the PropertyPane. the parameter is to indicate you just want to refresh only. So you service can support Primise, all you need to do is to call configureStart method.
Thoughts:
Since the data binding is very popular for client-side application development, I am surprise to see that the SharePoint Framework doesn't support the data binding or leverage some existing data binding library like Angular or Knockout.
I hope it helps.