UI Bootstrap和Angularjs datepicker选项卡和直接输入

时间:2014-02-13 18:35:46

标签: angularjs datepicker breeze angular-ui-bootstrap

我们正在使用Angularjs和Breeze开发基于HotTowel模板的SPA

我们在页面上有多个datePickers会给我们带来以下问题:

  • 当用户选中日期选择器时,datepicker会打开,但在用户选中下一个控件时不会关闭。由于日期选择器堆叠在ui的同一列中,这会导致下拉列表覆盖下面的字段。清除它们的唯一方法是在表单上的其他位置选择日期或单击

  • 在编辑绑定到数据模型的现有记录时,用户无法将日期键入输入区域。如果他们突出显示日期并尝试输入日期,则会删除现有日期,并且不允许用户键入新日期。如果他们单击X以清除输入字段,则无法键入新日期。如果他们将光标定位在日期末尾,退格,则日期消失,日历选择器设置为1902年1月。

基本上,如果用户愿意拿起鼠标并单击选择器中的日期并且从不尝试输入日期,那么这很好。这对我们的用户社区来说是不现实的。

这是html:

                                <label for="ApplicationCompleteDate" data-ng-show="vm.mode === 'edit'"><strong>Application Complete Date:</strong></label>
                            <div class="input-append" data-ng-show="vm.mode === 'edit'">
                                <span>
                                    <input name="ApplicationCompleteDate" type="text" class="form-control input-medium" tabindex="16" placeholder="{{vm.format}}"
                                           datepicker-popup="{{vm.format}}" close-text="Close" show-weeks='false'
                                           is-open="vm.applicationCompleteDateOpened"
                                           datepicker-options="vm.dateOptions"
                                           data-ng-model="vm.formData.dateApplicationComplete"
                                           data-ng-required="vm.applicationCompleteDateRequired"
                                           data-ng-readonly="(!user.isInUserGroup && vm.mode === 'new') || (!user.isInCPUGroup && vm.mode === 'edit')" />
                                </span>
                                <span class="add-on">
                                    <a href="#" data-ng-click="vm.applicationCompleteDateOpen($event)"><i class="icon-calendar"></i></a>
                                </span>
                            </div>
                            <label for="DecisionDatePicker" data-ng-show="vm.mode === 'edit'"><strong>Decision Date:</strong></label>
                            <div class="input-append" data-ng-show="vm.mode === 'edit'">
                                <span>
                                    <input name="DecisionDatePicker" id="ddpID" type="text" class="form-control input-medium" tabindex="14" placeholder="{{vm.format}}"
                                           datepicker-popup="{{vm.format}}" close-text="Close" show-weeks='false'
                                           is-open="vm.decisionDateOpened"
                                           datepicker-options="vm.dateOptions"
                                           data-ng-model="vm.formData.dateDecision"
                                           data-ng-required="vm.decisionDateRequired"
                                           data-ng-readonly="(!user.isInUserGroup && vm.mode === 'new') || (!user.isInCPUGroup && vm.mode === 'edit')" />
                                </span>                                    
                                <span class="add-on">
                                    <a href="#" data-ng-click="vm.decisionDateOpen($event)"><i class="icon-calendar"></i></a>
                                </span>
                            </div>
                            <label for="DateClosedPicker" data-ng-show="vm.mode === 'edit'"><strong>Closed Date:</strong></label>
                            <div class="input-append" data-ng-show="vm.mode === 'edit'">
                                <span>
                                    <input name="DateClosedPicker" type="text" class="form-control input-medium" tabindex="15" placeholder="{{vm.format}}"
                                           datepicker-popup="{{vm.format}}" close-text="Close" show-weeks='false'
                                           is-open="vm.dateClosedOpened"
                                           datepicker-options="vm.dateOptions"
                                           data-ng-model="vm.formData.dateClosed"
                                           data-ng-required="false"
                                           data-ng-readonly="(!user.isInUserGroup && vm.mode === 'new') || (!user.isInCPUGroup && vm.mode === 'edit')" />
                                </span>                                    
                                <span class="add-on">
                                    <a href="#" data-ng-click="vm.dateClosedOpen($event)"><i class="icon-calendar"></i></a>
                                </span>
                            </div>

我们正在使用与ng-model的双向绑定。

任何帮助都将不胜感激。

由于

3 个答案:

答案 0 :(得分:2)

有同样的问题,我发现了有问题的代码: 它在breeze.debug.js中的第4786行

    // exit if no change - extra cruft is because dateTimes don't compare cleanly.
if (newValue === oldValue || (dataType && dataType.isDate && newValue && oldValue && newValue.valueOf() === oldValue.valueOf())) {
    return;
}

问题是angulars dirty checker只是在做===所以最后它会覆盖视图值,因为它与模型中的不一样(因为breeze跳过了更新)。如果省略||之后的部分你可以正常输入数值,然后我遇到了一系列不同的问题。

这是角度观看数据和微风之间的不匹配。我希望沃德看到这一点。我拿出一张票。不知道什么是处理它的好地方,但我认为微风将是那个(因为角度与pojos工作正常)。我会在没有更新本身的副作用的情况下更新引用。

答案 1 :(得分:0)

如果你想让我调查一下,我需要一个repro来工作。在plunker中的东西会很好。

我认为我们不能改变我们的财产测试。有充分理由我们去了那么多麻烦。 Angular没有任何DataType概念,因此无法完成我们的工作。

但我们应该能够找到一个合适的解决方案,可能涉及Angular。例如,您可以为此编写一个简单的指令。您可以使用现有的Ng来处理它;我隐约回想起你可以指定一个可以复制breeze逻辑的绑定解析器。自从我看到它以来已经太久了,但我认为它就在那里。

答案 2 :(得分:0)

我遇到了同样的问题并通过在视图模型上创建一个本地范围的占位符变量来解决它,以便绑定到日期选择器。

<input type="text"
    class="form-control"
    datepicker-popup="M/d/yyyy"
    is-open="vm.openedStartDate"
    ng-model="vm.selectedStartDate"
    close-text="Close"
    show-button-bar="false" />

这允许使用日期选择器的所需行为。

然后我在保存更改之前将breeze实体值设置为此局部变量:

 task.StartDate = vm.selectedStartDate;
 task.EndDate = vm.selectedEndDate;
 datacontext.saveChanges();

它并不完美,但对于您所描述的问题,这是一个可行的解决方法。