我有一个视图,显示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());
}
});
});
但是视图没有从模型中获取数据,并且模型中的更改未在视图中更新。此方法中是否有任何错误,或者我们如何将托管对象的属性绑定到视图?
答案 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:
链接: https://embed.plnkr.co/bWFidnHVabwaoqQV
如您所见,绑定ManagedObjectModel
无缝地工作。
答案 2 :(得分:1)
我无法对此进行测试,因此可能存在以下问题,但其目的是:
{name: 'Naveen'}
的视图。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。