Search code examples
sapui5

Is it possible to bind sap.ui.base.ManagedObject to the view?


I have a view that shows the employee name in the sap.m.Input control as below

<mvc:View
  controllerName="com.naveen.test.managedobject.controller.Employee"
  xmlns="sap.m"
  xmlns:mvc="sap.ui.core.mvc"
  height="100%"
>
  <Input
    value="{/name}"
    liveChange="onDataChange"
    type="Text"
  />
</mvc:View>

And the model class is as shown here based on this hint.

sap.ui.define([
  "sap/ui/base/ManagedObject"
], function(ManagedObject) {
  "use strict";

  return ManagedObject.extend("com.naveen.test.managedobject.model.Employee", {
    metadata: {
      properties: {
        name: {
          type: "string",
          defaultValue: ""
        }
      }
    },

    set name(iName) {
      this.setName(iName);
    },

    get name() {
      return this.getName();
    }

  });
});

And in the controller, I am just creating one object of Employee model and setting it on the view as below.

sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/ui/model/json/JSONModel",
  "com/naveen/test/managedobject/model/Employee"
], function(Controller, JSONModel, Employee) {
  "use strict";

  return Controller.extend("com.naveen.test.managedobject.controller.Employee", {
    onInit: function() {
      var employee = new Employee({
        name : "Naveen"
      });
      this.model = new JSONModel(employee);
      this.getView().setModel(this.model);
    },

    onDataChange: function(oEvent) {
      var value = oEvent.getParameter("value");
      console.log("Value in control", value);
      console.log("Value in model", this.model.getData().getName());
    }

  });
});

But the view is not taking the data from the model and changes in the model are not updated in the view. Is there any error in this method or how can we bind the managed object's property to the view?


Solution

  • Since 1.58, there are no workarounds needed anymore thanks to the ManagedObjectModel (aka. "MOM").

    sap.ui.model.base.ManagedObjectModel
    The ManagedObjectModel class can be used for data binding of properties and aggregations for managed objects.

    Its constructor accepts anything that is extended from a ManagedObject meaning it can be even used with the UIComponent.

    sap.ui.define([
      "sap/ui/core/UIComponent",
      "sap/ui/model/base/ManagedObjectModel",
    ], function (UIComponent, MOM) {
      "use strict";
    
      return UIComponent.extend("my.Component", {
        metadata: {
          manifest: "json",
          properties: {
            "myProperty": {
              type: "string",
              defaultValue: "Hello MOM"
            }
          }
        },
    
        init: function () {
          UIComponent.prototype.init.apply(this, arguments);
          this.setModel(new MOM(this), "component");
        },
    
        // ...
      });
    });
    

    Then in the view: <Input value="{component>/myProperty}"/> which outputs "Hello MOM" by default.

    Internally, MOM is also used by UI5 for resolving event handlers that contain $source as one of the parameters.


    Here is a demo with the "Employee" example mentioned in the question. The following ManagedObjects were created for the purpose of the demo:

    • ManagedObject "Department" with aggregation "employees"
    • ManagedObject "Employee" with property "name"

    Sample: https://embed.plnkr.co/bWFidnHVabwaoqQV

    UI5 ManagedObjectModel ManagedObjects

    UI5 ManagedObjectModel binding

    As you can see, binding ManagedObjectModel works seamlessly.