“setInitialFocusId” error after _oDialog.destroy()

2019-08-12 14:09发布

问题:

I get the error following error when trying to open a Dialog fragment a second time after calling this._oDialog.destroy():

Uncaught TypeError: Cannot read property 'setInitialFocusId' of null

My problem is like the problem stated here: How to clear dialog/xmlfragment content after close? However, the solution apparently just seems to be "Don't use the property setInitialFocus", which I do not use anywhere in my code.

Controller

openDialog: function() {
  if (!this._oDialog) {
    this._oDialog = sap.ui.xmlfragment("myFragmentPath", this);
    this.getView().addDependent(this._oDialog);
  }
  this._oDialog.open();
},

onExit: function () {
  if (this._oDialog) {
    this._oDialog.destroy();
  }
},

afterClose: function () {
  if (this._oDialog) {
    this._oDialog.destroy();
  }
},

handleClose: function (oEvent) {
  this._oDialog.close();
}

Dialog Fragment

<Dialog xmlns="sap.m" afterClose=".afterClose">
  <!-- ... -->
</Dialog>

Main XML View

<Button press=".openDialog" />

Additional info:

  • The error message occurs in the Controller line when this._oDialog.open(); is called.
  • I am using the sap library version 1.60.1.

回答1:

afterClose: function () {
  if (this._oDialog) {
    this._oDialog.destroy();
    this._oDialog = null; // make it falsy so that it can be created next time
  }
},

After close, the dialog is destroyed in your code. However, the this._oDialog is still there.

Since this._oDialog is not a falsy value but just a destroyed dialog instance, there is no new Dialog created in openDialog() second time. Hence you're trying to call .open() from a destroyed dialog.

When the dialog is destroyed, its internal property oPopup is set to null, which explains the error message.


Notes

  • There is actually no need to destroy the dialog after close or in onExit. When the view gets destroyed, the dialog will be destroyed automatically since it's dependent to the view.
  • As of UI5 version 1.58, there is a new asynchronous API: sap/ui/core/Fragment.load. Please replace the old sap.ui.xmlfragmnet with the new API since the old one fetches the fragment via sync XHR.

  • Another option is to add <core:Fragment fragmentName="..." type="XML" /> to the <dependents> aggregation of a certain control within the view, something like this.