TinyMCE 4绑定OData后会消失属性

TinyMCE4 will be disappeared when it has been bund to OData property

我有一个智能表单,它有一个用于获取 RichTextEditor 的容器:


<smartForm:GroupElement label="{/#Report/Detail/@sap:label}" visible="{= (${appView>/appMode} === 'edit') }">
        <VBox id="RichTextEditorContainer" visible="{= (${appView>/appMode} !== 'review') }" app:objectId="{ path:'Id', events: { change: '.onBindingObjectChange'}}" width="100%">
            <!-- Insert RichTextEditor by JS-->
        </VBox>
</smartForm:GroupElement>

正如here所说:

Make sure you destroy the RichTextEditor instance instead of hiding it and create a new one when you show it again.

我没有在 xml 中创建编辑器,而是通过事件注入它:

onBindingObjectChange: function (oEvent) {
    if (this._oRTXE) {
        this._oRTXE.destroy();
    }
    var oBox = this.getView().byId("RichTextEditorContainer");
    oBox.removeAllItems();
    this._oRTXE = new RichTextEditor({
        value: "{Detail}",
        editable: true,
        height: "120px",
        width: "100%",
        wrapping: false,
        editorType: "TinyMCE4",
        showGroupClipboard: false,
        showGroupFontStyle: false,
        showGroupStructure: false,
        showGroupTextAlign: false
    });
    oBox.insertItem(this._oRTXE);

}

问题是,当用户尝试快速输入时,它会显示 <p>xyz</p> 一秒钟,然后文本编辑器就会消失。请看下图:

作为解决方法,如果我删除 value: "{Detail}"(这会产生绑定),那么这个问题就不会发生。此外,如果我将其绑定更改为 JSON 模型,也不会发生此错误。

问题是 RichTextEditor 的 change 事件。虽然在离开焦点或按回车键后发生更改事件的文档中已写明,但当用户在首次输入焦点后开始输入时也会发生。这是我的工作。将 RichTextEditor 绑定到 JSON 模型,并通过自定义事件更新 oData。

<smartForm:GroupElement label="{/#Report/Detail/@sap:label}" visible="{= (${appView>/appMode} === 'edit') }">
        <VBox id="RichTextEditorContainer" visible="{= (${appView>/appMode} !== 'review') }" app:objectId="{ path:'Id', events: { change: '.onBindingObjectChange'}}" 
app:detail="{ path:'Detail', events: { change: '.onBindingTextChange'} }"
width="100%">
            <!-- Insert RichTextEditor by JS-->
        </VBox>
</smartForm:GroupElement>
/** 
 * Event is fired when the data binding happen on RichTextEditor for object id 
 * @public 
 * @param {sap.ui.base.Event} oEvent pattern match event of data changed 
 */
onBindingObjectChange: function (oEvent) {
    var oBox = this.getView().byId("RichTextEditorContainer");
    if (this._oRTXE && this._oRTXE.data("objectId") === oBox.data("objectId")) {
        return;
    } else if(this._oRTXE) {
        this._oRTXE.destroy();
    }
    
    oBox.removeAllItems();
    this._oRTXE = new RichTextEditor({
        value: "{viewModel>/Detail}",
        editable: true,
        height: "120px",
        width: "100%",
        wrapping: false,
        editorType: "TinyMCE4",
        showGroupClipboard: false,
        showGroupFontStyle: false,
        showGroupStructure: false,
        showGroupTextAlign: false,
        change: this.onTextChanged.bind(this)
    }).attachBrowserEvent("focusin", () => {this._oRTXE.bHasFocus = true;})
      .attachBrowserEvent("focusout", () => {this._oRTXE.bHasFocus = false; this._checkWaitingChanges();});
    this._oRTXE.data("objectId", oBox.data("objectId"));
    oBox.insertItem(this._oRTXE);
},

/** 
 * Event is fired when the data binding happen on RichTextEditor for text
 * @public 
 * @param {sap.ui.base.Event} oEvent pattern match event of data changed 
 */
onBindingTextChange: function (oEvent) {
    var oBox = this.getView().byId("RichTextEditorContainer");  
    this.getModel("viewModel").setProperty("/Detail", oBox.data("detail"));
},

/** 
 * Event is fired when the text changed on RichTextEditor by user
 * @public 
 * @param {sap.ui.base.Event} oEvent pattern match event of text changed 
 */
onTextChanged: function (oEvent) { 
    this.getModel("viewModel").setProperty("/LastDetail", oEvent.getParameter("newValue"));
    this._oRTXE.bWaitingChanges = true;
    if(this._oRTXE.bHasFocus === false){
        this._oRTXE.bWaitingChanges = false;
        var sNewValue = oEvent.getParameter("newValue"),
            oBox = this.getView().byId("RichTextEditorContainer"),
            oContext = oBox.getBindingContext(),
            oModel = oContext.getModel(),
            sBindingPath = oContext.getPath() + "/Detail";
        oModel.setProperty(sBindingPath, sNewValue);
    }
},

// Just checks if there is any changes that has not yet been written in the odata model 
_checkWaitingChanges: function(){
    if(this._oRTXE.bWaitingChanges === true){
        this._oRTXE.bWaitingChanges = false;
        var sNewValue = this.getModel("viewModel").getProperty("/LastDetail"),
            oBox = this.getView().byId("RichTextEditorContainer"),
            oContext = oBox.getBindingContext(),
            oModel = oContext.getModel(),
            sBindingPath = oContext.getPath() + "/Detail";
        oModel.setProperty(sBindingPath, sNewValue);
    }
}