1

我有一个来自 Breeze 的实体,它可能有 20 个左右的属性,但是我想将该实体包装在一个视图模型中,并且只将这几个属性公开为 ko.observable()。我如何管理所有进行属性更改通知?

在 c# 中,我会做这样的事情:

public double OtherSalesPercent
{
 get { return Model.OtherSalesPercent; }
 set 
 { 
  if (Model.OtherSalesPercent != value)
  {
   Model.OtherSalesPercent = value;
   OnPropertyChanged("OtherSalesPercent");
  }
 }
}

更新 杰伊感谢您的回复。我知道 beze 可以做到这一点。但是,我不希望我的视图直接绑定到实体,而是视图模型。所以想想一个叫做苹果的观点。苹果正在显示苹果视图模型列表。每个苹果实体都有 30 个不同的属性,但我只想在苹果视图模型上公开这 30 个属性中的 3 个。所以,我想在苹果视图模型上创建 3 个 ko.observable 属性,这些属性将在苹果实体上显示这 3 个属性。到目前为止我所拥有的是“工作”,但我认为它不是最干净的。这是名称属性:

var appleViewModel = function(appleEntity) {
   var backingEntity = appleEntity;

   var name = ko.observable(locationEntity.name());
   name.subscribe(function(newValue) {
       backingEntity.name(newValue);
   });

   var vm = {
    name: name
   };

   return vm
};

另一个重要原因是我正在使用 jqxGrid,但它们在绑定到 Breeze 实体时遇到问题。所以我真正想要的是一个可以显示这些属性的 appleViewModel,但是,如果我更改实际的苹果实体(如在 cancelChanges 中),我希望 UI 从实体中获取该更改)。

更新 2

这似乎给了我我想要的一切并绑定到 jqxGrid

var createViewModel = function(appleEntity) {
    var entity = appleEntity;

    var name = ko.observable(entity.name());
        name.subscribe(function(newValue) {
            entity.name(newValue);
        });
        entity.name.subscribe(function(newValue) {
            name(entity.name());
        });

        var vm = {
            name: name
        };

        return vm;
};  

但这对我来说似乎是错误的。我基本上想要双向绑定。因此,当我更改视图模型名称属性时,它会更改支持实体名称......如果我更改支持实体名称,它将更新视图模型名称属性。

谢谢!

4

2 回答 2

0

我认为这就是您要寻找的ko.computed

var data = {
    OtherSalesPercent: 0.99
};


function Model(data) {
    this.OtherSalesPercentValue = ko.observable(data.OtherSalesPercent);

    this.OtherSalesPercent = ko.computed({
        read: function () { 
            return Model.OtherSalesPercentValue(); 
        },
        write: function (value) {
            if (this.OtherSalesPercentValue() != value) {
                this.OtherSalesPercentValue(value);
            }
        },
        owner: this
    });
}

例子

于 2013-04-04T21:25:38.927 回答
0

如果我理解你的问题,你有几个选择。

首先,默认情况下,根据您选择的“模型库”的约定,微风使每个实体属性“可观察”。因此,为了清楚起见,如果您检索到轻风识别为实体的数据,并且轻风的模型库是“ko”(如果您没有配置,则为默认值),那么每个实体属性都将自动成为可观察的淘汰赛。

仅当您的查询返回“实体”时才会发生这种情况。Breeze 通过查找客户端 MetadataStore 中定义的相应 entityType 来确定您的查询结果是否包含实体。

如果返回的数据不是实体或实体集合,那么微风只会将其原始返回。如果您仅对选定字段执行投影,则可能会发生这种情况。IE

var query = EntityQuery.from("Orders").select("customer, orderDate");

在这种情况下,promise 回调中返回的查询结果中的每个项目将只是一个具有两个简单属性的对象,一个“客户”和一个“订单日期”,这两个属性都是不可观察的。

不过,根据您的问题,我想知道您是否只想将每个服务器端实体的子集公开给客户端,但仍需要更改管理和可观察性。如果是这种情况,您可以让服务器端方法返回 DTO,然后通过指定有关每个 DTO 形状的元数据告诉微风客户端这些是“实体类型”。这可以在客户端上最轻松地完成,方法是对您计划返回的每个 DTO 形状使用 MetadataStore.addEntityType 方法。微风文档对此主题进行了更详细的介绍。

我不确定这是否是您要问的,但是...我希望它有所帮助。

于 2013-04-05T02:26:51.603 回答