【问题标题】:highlight a changed property on model load突出显示模型加载时更改的属性
【发布时间】:2016-02-01 18:28:22
【问题描述】:

我有一个表格,其中数据由我的控制器中的 javascript 间隔函数定期更新:

var model = this.getview().getModel();  
var updateModel = setInterval(function(){
  model.loadData('path/to/my/data.json');  
}, 30000)  

这基本上是在公共监视器上显示数据摘要的静态显示。

我希望能够在属性发生更改时突出显示,所以我一直在尝试在控件发生更改时向控件添加一个类。然后该类将使用 CSS 以某种方式突出显示这一点。

<Table items="{items}">  
  <columns>  
    <Column/>  
    <Column/>  
  </columns>  
  <items>  
    <ColumnListItem>  
      <cells>  
        <Text   
          text="{name}" />  
        <ObjectStatus  
          text="{value}"  
          state="{  
            path: 'value',  
            formatter: '.formatter.redOrGreen'  
          }"/>  
      </cells>  
    </ColumnListItem>  
  </items>  
</Table>  

因此模型每 30 秒更新一次。如果 {value} 字段发生变化,我想向 ObjectStatus 控件添加一个类。

目前我只是使用 JSON 模型进行本地开发,看看这是否可行,但在生产中它将是一个 oData 服务。

【问题讨论】:

  • 您可以JSON.stringify() 您的数据并比较两个字符串 - 更新前后。例如如何做到这一点,看看这篇文章:link.
  • 也许比较整个字符串化的数据是不够的(因为它没有突出 what 发生了变化,只有 多少)。我建议将最后提取的数据与当前数据进行比较,并将结果绑定到您的视图。 stackoverflow.com/questions/8572826/…
  • Marc 是对的,这对我不起作用,因为我需要知道发生了什么变化以及如何变化。我已经设法解决了这个问题,类似于@schnoedel 的答案,我将在单独的答案中写出来。

标签: sapui5


【解决方案1】:

感谢您的回答,我设法解决了这个问题,但是这里的答案并没有完全涵盖我的方法。我就是这样做的:

自从我发布问题以来,对此的要求略有变化。我需要指出是否发生了变化,以及价值是否上升或下降。我还需要指出某些东西是否高于或低于某个值。如果将来有任何其他需求,我还想制定一个可以轻松适应的解决方案。当后端服务启动并运行时,这也需要很容易地适应 oData。

首先(也是关键)是设置一个复制模型,所以这进入了我的 component.js 文件。我只是在这里复制模型,以便旧值和新值不变,使格式化程序功能在第一页加载时起作用:

var oModel = new JSONModel('/path/to/data.js');
this.setModel(oModel, 'model');
this.setModel(oModel, 'oldModel');

然后,在视图的控制器中,我将旧数据的副本放入我附加到视图的旧模型中,然后更新新模型。我在渲染后挂钩中执行此操作以优化初始页面加载。

onAfterRendering: function(){
  var thisView = this.getView();
  var updateModel = function(){
    var oldData = thisView.getModel('model').getData();
    var oldModel = new JSONModel(oldWharehousesData);
    thisView.setModel(ollModel, 'oldModel');

    //update model
    var newModel = thisView.getModel('model');
    model.loadData('/path/to/data.js');

  };
  window.refershInterval = setInterval(updateModel, 30000);
}

然后我可以在我的 XML 视图中将新旧值输入到格式化程序并输出几个自定义数据属性:

<core:CustomData
    key="alert-status"
    value="{
      parts: [
        'model>Path/To/My/Property',
        'oldModel>Path/To/My/Property'
        ],
      formatter: '.formatter.alertStatus'
      }"
    writeToDom="true"/>
</customData>

我的 formatter.js :

alertStatus: function(newValue, oldValue){
  var alertNum = 25;
  if(newValue < alertNum && oldValue >= alertNum) {
    return 'red';
  } else if (newValue >= alertNum && oldValue < alertNum) {
    return 'green';
  } else {
    return 'none';
  }
}

然后,我可以拥有任意数量的自定义数据属性,通过它们自己的格式化程序函数运行它们,该函数可以根据我的喜好设置样式,例如:

compareValues: function(newValue, oldValue) {
  if (newValue > oldValue) {
    return 'higher';
  } else if (newValue < oldValue){
    return 'lower';
  } else {
    return 'false';
  }
}

【讨论】:

  • 这两个模型的有趣方法,甚至比我的 diff-model 建议更好,因为您可以比较格式化程序中的值。
  • 您还有表格/列表吗?如果是这样,您是否找到了对两个模型都使用聚合列表绑定上下文的可能性? Afaik 使用列表绑定,一个模型只有一个上下文。
  • 它仍然在一个表中,但没有聚合绑定。我也没有在原始示例中使用它。想到现在如何做到这一点,这让我有点头疼:) 编辑:实际上我在原始示例中确实有这个。对要求的更改意味着实际上不需要这样做。
【解决方案2】:

我已经建立了一个example on JSBin

首先你必须得到接收到的数据。您可以使用 Model.attachRequestCompleted 事件:

    this.model = new sap.ui.model.json.JSONModel();
    this.model.attachRequestCompleted(this.onDataLoaded, this);

在事件处理程序onDataLoaded 中,您可以检索 JavaScript 对象并将其与保存的副本进行比较。您必须编写指示更改数组项本身的标志。 (正如 Marc 在他的评论中建议的那样,将其存储在一个单独的模型中是行不通的,因为在您的聚合绑定中,您的数组项只有一个上下文。)

最后你必须将newData 对象保存为this.oldData 以供下一个请求。

  onDataLoaded:function(){
    var newData = this.model.getProperty("/");
    if (this.oldData){
      //diff. You should customize this to your needs.
      for(var i = 0, length = Math.min(newData.items.length, this.oldData.items.length); i< length; i++){
        newData.items[i].valueChanged = newData.items[i].value !== this.oldData.items[i].value;
        newData.items[i].nameChanged = newData.items[i].name !== this.oldData.items[i].name;
      }
    }
    this.oldData = newData;
    this.getView().getModel().setProperty("/",newData);
  },

然后您可以将 ObjectState 状态属性绑定到标志:

<ObjectStatus  
      text="{value}"
      state="{= ${valueChanged} ? 'Warning':'None' }"/>  

如果您想更改整行的背景颜色或类似的东西,您可以应用Bernard's 答案并在customData attribute 中使用标志。

【讨论】:

    【解决方案3】:

    您可以使用&lt;customData&gt; 标签 这允许将自定义属性插入到由 XML 到 HTML 转换过程产生的 HTML 中

    例如,在下面的示例中,我添加了一个自定义属性(我自己的) - 此代码在相关 HTML 元素(&lt;SPAN&gt; 标记)中生成以下属性 data-colour - 使用 Chrome 等检查相关元素.

    <customData>
       <core:CustomData writeToDom="true" key="colour" value="{vproducts>ListCostColour}" />
    </customData>
    

    然后您可以在您自己的样式表中为该属性创建一个样式,如下所示(并在您的 manifest.json 中引用它)

        [data-colour="red"] {
            background-color: #ffd1cc;
        }
        [data-colour="orange"] {
            background-color: rgba(255, 243, 184, 0.64);
        }
        [data-colour="green"] {`enter code here`
             background-color: rgba(204, 255, 198, 0.97);
         }
    

    【讨论】:

      猜你喜欢
      • 2013-11-24
      • 2017-07-20
      • 1970-01-01
      • 2023-03-11
      • 2013-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多