Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

sapui5 - attachChange callback not fired for getBinding("text") of sap.m.Button

onInit(): function{
    this._oSelectedTrainingsModel = new sap.ui.model.json.JSONModel([]);
    this.getView().setModel(this._oSelectedTrainingsModel, "selectedTrainings");
},

onAfterRendering: function() {
    this.getView().byId("ViewSelectionButton").getBinding("text").attachChange(this._onTextUpdated, this);
},

In the XML view I have this binding:

<Button id="ViewSelectionButton"
    class="magnificationPrep"
    icon="sap-icon://cart-full"
    tooltip="Share"
    text="{i18n>viewTrainingsButton} ({= %{selectedTrainings>/}.length })"
    press="handlePressViewSelection"
/>

At some point in the controller, an object is added to the _oSelectedTrainingsModel:

this._oSelectedTrainingsModel.getProperty("/").push(oNewSelection);

At this point, the bound text property is changed and thus I'm expecting a call to the callback function _onTextUpdated.

The model is empty, this is probably part of the issue?

...getBinding("text") object in onAfterRendering()

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

In order to update the UI via binding, you have to use setProperty with the same path used in the binding definition which triggers checkUpdate (<-- fires change event).

The problem was that you mutated the selectedTrainings-array manually via getProperty(...).push. This bypasses notifying UI5 about the changes since getProperty doesn't trigger checkUpdate. Therefore..:

Instead of

this._oSelectedTrainingsModel.getProperty("/").push(oNewSelection);
this._oSelectedTrainingsModel.refresh(true);

Do

const newArray = this._oSelectedTrainingsModel.getProperty("/").concat(oNewSelection);
this._oSelectedTrainingsModel.setProperty("/", newArray);

This alone is sufficient to update the UI thanks to the one-way data binding:

One-way binding means a binding from the model to the view; value changes in the model update all corresponding bindings and the view (and not the other way around).

There is no need to call refresh(true) which is an indication of anti-pattern. Here is a demo: stackoverflow.com/a/48226884


Btw: the module returned by getBinding("text") is CompositeBinding since there are more than one binding definitions involved. The CompositeBinding however does not offer attachChange for public use. So it shouldn't have been used anyway.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...