Can't get changed property from attachProperty

2019-07-24 22:55发布

I would like to know which property in the JSON model has changed when modified by a view. For a test I took OpenUI5 walkthrough example and added the following lines in the application controller

oProductModel.attachPropertyChange( function(oEvent){
   console.log("event: ", oEvent);
}, this); 

When I change a property in the text input, the function in the attachPropertyChange is called but oEvent object is empty as I print it in console.

I know I could connect to text input change event, but I would like to use attachPropertyChange in case there would be multiple views of the same model.

标签: sapui5
2条回答
beautiful°
2楼-- · 2019-07-24 23:59

As far as I understood, you'd like to avoid using the change event of the Input control because there is no information about which property in the model has changed. However, you can still get all those information within the change handler via:

  • event.getSource().getBinding(/*controlPropertyName*/).getPath() to get the name of the bound property, or
  • event.getSource().getBindingContext(/*modelName*/).getPath(/*suffix*/) to get the path of the bound context. The getPath here awaits an optional suffix that will be appended to the context path with a "/" in between.

You can combine those two APIs to get an absolute path in case the property binding was relative. E.g.:

onInputChange: function(event) {
  const input = event.getSource();
  const property = input.getBinding("value").getPath(); // "myProperty"
  const absolutePath = input.getBindingContext().getPath(property) // "/0/myProperty"
},

Demo

sap.ui.getCore().attachInit(() => sap.ui.require([
  "sap/ui/model/json/JSONModel",
  "sap/m/MessageToast",
], (JSONModel, MessageToast) => sap.ui.xmlview({
  viewContent: `<mvc:View
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m"
    height="100%"
    displayBlock="true"
  >
    <App>
      <Page title="Type Something"
        content="{myModel>/Products}"
      >
        <Input
          placeholder="Input"
          value="{myModel>ProductID}"
          change=".onChange"
        />
      </Page>
    </App>
  </mvc:View>`,

  controller: {
    onChange: function(event) {
      this.showPropertyInfo({
        bindingContext: event.getSource().getBindingContext("myModel"),
        propertyPath: event.getSource().getBinding("value").getPath(),
        of: event.getSource(),
      });
    },

    showPropertyInfo: ({propertyPath, bindingContext, of}) => MessageToast.show(
      `Property : "${bindingContext ? propertyPath : propertyPath.substr(1)}"
       Absolute Path : "${bindingContext ? bindingContext.getPath(propertyPath) : propertyPath}"`, {
      duration: 999999,
      width: "18rem",
      at: "end bottom",
      of,
    }),

  },
  async: true,

}).setModel(new JSONModel({
  Products: [{
    ProductID: "",
  }, {
    ProductID: "",
  }, {
    ProductID: "",
  }],
}), "myModel").placeAt("content")));
<script id="sap-ui-bootstrap"
 data-sap-ui-libs="sap.ui.core, sap.m"
 data-sap-ui-preload="async"
 data-sap-ui-theme="sap_belize"
 data-sap-ui-xx-waitForTheme="true"
 src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
></script><body id="content" class="sapUiBody"></body>

Note: Currently, the API getPath of Binding is not visible in the API Reference due to the missing @public annotation. However, that's an issue of UI5 documentation which will be fixed soon or later. Until then, the source code can be found here.

查看更多
Deceive 欺骗
3楼-- · 2019-07-25 00:00

You can use change event for all input field in UI, and write event handling method in the controller. You will get the property as well as value in the oEvent of the event handling method easily. I hope you understood.

查看更多
登录 后发表回答