0

我有一个 AngularJS 应用程序,我想在其中编辑由 ASP Web API 通过 BreezeJS 公开的 Date 对象。当我尝试在 HTML 表单中编辑此字段时,它并不能正常工作。它似乎编辑了对象的一部分,或者根本不绑定到日期输入类型。

我想知道用 BreezeJS 编辑 HTML 表单中的日期字段的最佳方法是什么。我找不到任何有关如何以适当方式解决此问题的资源。

我自己的猜测是:

  1. 使用基于原始日期的额外字段扩展 Breeze 实体,并使用 getter/setter。
  2. 不在 WebAPI 中使用日期字段,但感觉不对。

代码

在我的 Angular 控制器中,我通过存储库模式从 Breeze 获取对象:

datacontext.session.getById(id)
    .then(function (data) {
         return vm.session = data;
});

之后 vm.session 被 Breeze 对象填充,如下所示:

[{
    "$id":"1",
    "$type":"TestApp.Model.Session, TestApp.Model",
    "Id":3,
    "Name":"Second session",
    "StartDate":"2014-10-12T00:00:00.000",
}]

现在在我的 HTML 表单中,我像这样绑定:

<input type="date" ng-model="vm.session.startDate" placeholder="Start Date">

如果我在输入字段中使用“文本”类型而不是“日期”类型,则会将此日期显示为“Sun Oct 12 2014 02:00:00 GMT+0200 (Romance Daylight Time)” 。

ng-model 字段的大小写是正确的,因为我使用它来创建 camelCase 字段:

breeze.NamingConvention.camelCase.setAsDefault();

所以这相当简单......我会尽快制作一个 JSFiddle 或 Plunker

4

1 回答 1

0

Date当您说它们在元数据中时,Breeze 将日期属性维护为 JavaScript对象。

Breeze 没有自己Date类型。

HTML5<input type="date" .../>日期选择器尚未得到广泛支持(请参见此处),因此我假设您依赖Angular 指令来帮助您。

该指令旨在绑定到字符串,而不是日期对象。这可能解释了为什么车轮脱落。

我很想争辩说 Ng 指令应该比这更聪明。它应该执行绑定到Date对象和日期字符串所需的操作。我可能会将其归档为错误。

如您所见,如果类型为“文本”,则 HTML 输入标记“正常工作”。显然日期显示和数据输入不是你想要的。

我认为理想的解决方案是有一个在日期对象和字符串值之间无缝转换的指令。可能可以通过装饰现有的 Ng 指令本身来完成。需要调查的东西;我们可以随时使用您的帮助;这是开源的:-)。

同时,您可以在自定义Session类型构造函数上创建定义的属性。

请参阅文档中的“自定义构造函数” 。这样的属性将包装startDate属性(startDateAsString?),解析文本并在输出时格式化为字符串。

这是一个生成日期包装器属性的通用函数:

// Example: addDateWrapperProperty(SessionCtor, 'startDate', 'startDateAsString');

function addDateWrapperProperty(ctor, propName, wrapperPropName) {

    Object.defineProperty(ctor.prototype, wrapperPropName, {
        get: function () { return this[propName].toString(); },
        set: function (value) { this[propName] = value; },
        enumerable: true,
        configurable: true
    });
}

使用它来定义您的startDateAsString包装器属性,然后在编辑时绑定到该属性(绑定到真实属性以进行只读显示)。

因为您不希望 Breeze 序列化它,所以在使用 Breeze 元数据注册该 ctor 之后将其添加到 ctor 中,如下所示。

我不确定这会给你你正在寻找的行为。我需要看看你的 jsFiddle 或 plunkr 才能确定。但我认为它会成功。让我们知道!

当然不是说这是最终的答案。我不确定那个答案是什么……尽管我正在考虑我所说的指令。

希望这能让你暂时摆脱困境。对不起,它是这样一个 PITA。谁知道 Ng 不会理解 Date 对象?

例子

这是从实际 Breeze 测试中提取的示例:

/////  Test it //////
var OrderCtor = function () { }; // do-nothing custom constructor

// register the ctor FIRST, then add the property
manager.metadataStore.registerEntityTypeCtor('Order', OrderCtor);

addDateWrapperProperty(OrderCtor, 'orderDate', 'orderDateAsString');

// create new order with a test date
var testDate = new Date(2014,0,1,13,30); // 1/1/2014 1:30 pm

var order = em.createEntity('Order', {
    companyName: "test cust",
    orderDate: testDate
});

// confirm can read the date through the wrapper property
expect(order.orderDate.value).to.equal(testDate.value,
    "'order.orderDate' should return " + testDate);
expect(order.orderDateAsString).to.equal(testDate.toString(),
    "'order.orderDateAsString' should return " + testDate.toString());


var testDate2 = new Date();

// update orderDate by way of the wrapper property
order.orderDateAsString = testDate2.toString();

// confirm the update worked
expect(order.orderDate.value).to.equal(testDate2.value,
    "after update, 'order.orderDate' should return " + testDate2);
expect(order.orderDateAsString).to.equal(testDate2.toString(),
    "after update, 'order.orderDateAsString' should return " + testDate2.toString());

// confirm it is not a breeze-tracked property
var propInfo = order.entityType.getProperty('orderDateAsString');
expect(propInfo).to.equal(null, "'Order.orderDateAsString' is not known to metadata ");
于 2014-11-20T02:05:25.080 回答