是否可以将sap.ui.base.ManagedObject绑定到视图?

时间:2017-08-09 13:21:30

标签: sapui5

我有一个视图,显示sap.m.Input控件中的员工姓名,如下所示

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

此处的模型类基于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();
    }

  });
});

在控制器中,我只是创建 Employee 模型的一个对象,并在视图上设置如下。

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

  });
});

但是视图没有从模型中获取数据,并且模型中的更改未在视图中更新。此方法中是否有任何错误,或者我们如何将托管对象的属性绑定到视图?

3 个答案:

答案 0 :(得分:2)

是的,这是可能的,但有一点解决方法。 我有一个自定义的BusinessObjectModel,它是标准JSONModel的继承,但模型中的每个条目实际上都是一个类的实例。

请参阅此github存储库: https://github.com/FiddleBe/UI5-BusinessObjectModel 它是如何将对象实例用作模型条目并将对象属性绑定到视图的示例。

其中还有许多其他功能,例如您可能不需要的离线持久性功能。

我的基础BusinessObject(您必须为您的员工继承)基于EventProvider而不是managedobject。但是由于managedobject继承了EventProvider,或许可以改变bas BusinessObject的扩展...无论如何..

一些重要的注意事项: 每当一个属性是&#34; set&#34;时,你需要引发一个事件(在我的实现中为PropertyUpdated)。 来自你的二传手:

this.fireEvent("propertyUpdated", {
     reason: sap.ui.model.ChangeReason.Binding,
     path: "/<yourpropertyname>",
     value: this.<yourproperty>
});

在模型继承中,您需要订阅条目集中存在的每个对象实例的此事件。你可以在setData继承

中做到这一点
ObjectModel.prototype.setData = function (oData, bMerge) {
   var aData = [];
   this.oData = [];

   if (oData instanceof Array) {
       aData = oData;
   } else {
       aData.push(oData);
   }

   for (var i = 0; i < aData.length; i++) {
       var oObject = aData[i];
       if (this.objectClass && oObject instanceof this.objectClass) {
         //is already an object instance.. don't change.
         oObject.attachPropertyUpdated({ basePath: "/" + i }, this.onPropertyUpdated, this);
       }else if (this.objectClass) {
          oObject = new this.objectClass.getObject(aData[i], "/" + i);
          oObject.attachPropertyUpdated({ basePath: "/" + i }, this.onPropertyUpdated, this);
        } else {
           oObject = aData[i];
        }
        this.oData = this.oData.concat(oObject);
    }

    arguments[0] = this.oData.concat();//not very clean

    Model.prototype.setData.apply(this, arguments);
};

还可以查看github中的库:https://github.com/FiddleBe/library 它包含更新的实施。

答案 1 :(得分:2)

自1.58以来,由于ManagedObjectModel(MOM),不再需要变通办法。

  

sap.ui.model.base.ManagedObjectModel
  ManagedObjectModel类可用于用于托管对象的属性和聚合的数据绑定

它的构造函数接受从ManagedObject扩展的任何内容,这意味着它甚至可以与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");
    },

    // ...

  });
});

然后在视图中<Input value="{component>/myProperty}"/>默认输出"Hello MOM"

在内部,MOM也用于XMLComposite控件和新event handling概念中。

这是一个带有问题中提到的“员工”示例的演示。为演示目的创建了以下ManagedObject:

  • 带有聚合“员工”的ManagedObject“部门”
  • ManagedObject“Employee”,其属性为“name”

链接: https://embed.plnkr.co/bWFidnHVabwaoqQV

UI5 ManagedObjectModel ManagedObjects

UI5 ManagedObjectModel binding

如您所见,绑定ManagedObjectModel无缝地工作。

答案 2 :(得分:1)

我无法对此进行测试,因此可能存在以下问题,但其目的是:

  • 实例化JSON模型并将其附加到包含{name: 'Naveen'}的视图。
  • 实例化指向JSON模型中名称的新Employee
  • 将员工附加到屏幕

如下所示:

this.getView().setModel(new JSONModel({name:'Naveen'}));

// this is UI5 databinding. `{/name}` references the variable called 'name'
// in the unnamed model, like above
var employee = new Employee({name: '{/name}'); 
this.getView().addContent(employee); 

您可能需要考虑阅读OpenUI5文档中的应用程序的演练,该文档将告诉您有关数据绑定的所有信息。 Here是最新版本(1.48)的链接,您也可以找到其他版本。

澄清封装,这是由JSON模型完成的。可以使用

访问数据
this.getModel().getProperty('/name') //get
this.getModel().setProperty('/name', 'NotNaveen') //set. 

这将通过绑定系统传播名称更改(在这种情况下,它将更改Employee中的名称)。

如果您希望模型中的输入字段绑定到name

this.getView().addContent(new Input({value: '{/name}'));

在构造函数中,设置您想要的任何结构并调用超级构造函数。它可以以与JSONModel相同的方式使用 - 绑定等 - 同时还可以对内部数据进行一些控制。

所以要真正回答你的问题:不,你不应该这样使用ManagedObject,使用JSONModel。