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);
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…