Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
721 views
in Technique[技术] by (71.8m points)

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

I have a smart form and it has a container for fetching a RichTextEditor in:


<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>

As it has been said here that:

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

I don't make the editor in xml and by an event inject it:

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);

}

The problem is, when user tries to type fast, it shows <p>xyz</p> for a second and then the text editor will be disappeared. Please look at the following picture:

enter image description here

As a work around if I remove value: "{Detail}" (that makes binding) then this problem will not happen. Also, if I change its binding to a JSON model also this error won't happen.

question from:https://stackoverflow.com/questions/65841223/tinymce4-will-be-disappeared-when-it-has-been-bund-to-odata-property

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The problem is the change event of the RichTextEditor. While it has been written in the documentation that change event happen after leaving focus or press enter but it will also happen when user starts for typing after first enter focus. Here is my work around. Bind the RichTextEditor to JSON model, and update oData by a customized event.

<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);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...