使用 ng-repeat、filter 和 uib-popup-datepicker 过滤 table 列结果

Using ng-repeat, filter, and uib-popup-datepicker to filter table column results

我有一个 angular 应用程序的常见场景,我正在工作,但无法解决此模式。我已经彻底搜索了这种情况的答案,但所有类似的问题似乎在我的应用程序中都不起作用或解决了 html5 输入类型日期元素和 ng-repeat 时排除时间的问题。

我需要使用类型为 'date' 的 html5 输入从 ng-repeat 中过滤项目(或者使用 Angular-UI-Bootstrap' s 'uib-popup-datepicker').

我能够将用户的输入存储在具有以下格式的 javascript 对象中('date' 属性 的名称可能会根据我所代表的日期而改变许多不同类型的对象,其中存储了多个日期):

输入字段 ng-model

search.date

javascript 对象

object.date

我相信我遇到的问题是 html5 输入类型日期元素 returns 是一个 JavaScript 日期对象,格式如下:

"2016-11-17T08:00:00.000Z"

我通过使用符合 HAL 的 REST API 收到的 JSON 结果的日期格式如下:

2016-11-17T09:30:00.000+0000

我只想过滤日期,不包括时间。我相信 ng-repeat 正在使用完整的日期(包括时间),通过删除任何不完全匹配的项目 Date/Time。这不是我想要的行为。我希望显示在筛选日期发生的所有项目。

这是页面呈现后的屏幕截图,后面是 HTML: HTML(省略面板及以上):

<div class="panel-body">
        <table id="outstandingBills" class="table table-striped table-hover">
            <thead>
            <th class="form-group checkbox">
                <span>Select to Bill</span><br>
                <label style="margin-top: 8px;">
                    <input type="checkbox" 
                           name="selectAll" 
                           value="true" 
                           ng-model="financeBillingCtrl.isAllSelected" 
                           ng-click="financeBillingCtrl.selectAll()" /> Select All
                </label>
            </th>
            <th>
                <label for="filter_name">Customer Name</label>
                <input type="input" 
                       class="form-control" 
                       id="filter_customer_name" 
                       name="filter_customer_name" 
                       placeholder="Filter by Name"
                       ng-model="search.customer.name" />
            </th>
                <th>
                    <label for="filter_bill">Bill Amount</label>
                    <input type="input" 
                           class="form-control" 
                           id="filter_bill_amount" 
                           name="filter_bill_amount" 
                           placeholder="Filter by Bill Amount"
                           ng-model="search.billAmount" />
                </th>
                <th>
                    <label for="filter_total">Open Total</label>
                    <input type="input" 
                           class="form-control" 
                           id="filter_open_total" 
                           name="filter_open_total" 
                           placeholder="Filter by Total Billable Amount"
                           ng-model="search.openTotal"/>
                </th>
                <th>
                    <label for="filter_date">Last Billed</label>
                    <div class="input-group">
                        <input type="text" 
                               class="form-control" 
                               uib-datepicker-popup 
                               ng-model="search.lastBillDate" 
                               ng-change="financeBillingCtrl.instanceType(search.lastBillDate)"
                               is-open="financeBillingCtrl.datepickerLastBilled.isOpen" 
                               datepicker-options="dateOptions" 
                               ng-required="false" 
                               close-text="Close" />
                        <span class="input-group-btn">
                          <button type="button" 
                                  class="btn btn-default" 
                                  ng-model="financeBillingCtrl.datepickerLastBilled.date"
                                  ng-click="financeBillingCtrl.toggleDatepicker(financeBillingCtrl.datepickerLastBilled)"><i class="glyphicon glyphicon-calendar"></i></button>
                        </span>
                    </div>
                </th>
            </thead>
            <tbody>
                <tr ng-repeat="customerBillingItem in financeBillingCtrl.customerBillingItems | filter: search | filter: {lastBillDate: search.lastBillDate}">
                    <td>
                        <input type="checkbox" 
                               name="bill" 
                               value="true"
                               ng-model="customerBillingItem.selected" />
                    </td>
                    <!--<td><a href="{{ mainCtrl.baseUrl }}/system{{ mainCtrl.parseLink( customerBillingItem.customer._links.subscriptions.href ) }}">{{ customerBillingItem.customer.name }}</a></td>-->
                    <td><a href="{{ mainCtrl.baseUrl }}/system/customers/1/vendorBillingItems/1/subscriptions">{{ customerBillingItem.customer.name }}</a></td>
                    <td>{{ customerBillingItem.billAmount | currency }}</td>
                    <td>{{ customerBillingItem.openTotal | currency }}</td>
                    <td>{{ customerBillingItem.lastBillDate | date }}</td>
                </tr>
            </tbody>
        </table>
    </div>

    <div class="panel-footer">
        Paging Here
    </div>
</div>
<!-- RESULTS - END -->
<pre>
search.lastBillDate:
{{ search.lastBillDate }}

items.lastBillDate: 
<span ng-repeat="item in financeBillingCtrl.customerBillingItems">{{ item.lastBillDate }}<br></span>
</pre>

下面是使用过滤器后的页面截图(我使用

显示对象的当前值):

控制器代码:

/***************************** DATE PICKER - START *****************************/

    // CONFIGURATION - Date Pickers
    // Datepicker - Filter: Start Date
    financeBillingCtrl.datepickerFilterStartDate = {
        isOpen : false,     // Default the lastBilled datepicker to closed
        date: new Date()    // Used with ng-model to set the Default Date Selection
    };
    // Datepicker - Filter: End Date
    financeBillingCtrl.datepickerFilterEndDate = {
        isOpen : false,     // Default the lastBilled datepicker to closed
        date: new Date()    // Used with ng-model to set the Default Date Selection
    };
    // Datepicker - Table Column Filter: Last Billed
    financeBillingCtrl.datepickerLastBilled = {
        isOpen : false      // Default the lastBilled datepicker to closed
    };

    // Events - Date Pickers
    financeBillingCtrl.toggleDatepicker = function(datepicker) {
        console.log(financeBillingCtrl.CLASSNAME + ".toggleDatepicker()");
        console.log("PRE__CHANGE - datepicker.isOpen: " + datepicker.isOpen);
        // Update the 'isOpen' variable on the supplied datepicker
        datepicker.isOpen = ! datepicker.isOpen;
        console.log("POST_CHANGE - datepicker.isOpen: " + datepicker.isOpen);
    };

    financeBillingCtrl.instanceType = function(instance) {
        console.log(financeBillingCtrl.CLASSNAME + ".instanceType(instance: " + instance + ")");
        var result = "";
        if (instance == null) {
            result += "Vanilla null, ";
        }
        if (instance == undefined) {
            result += "Vanilla undefined, ";
        }
        if (angular.isDefined(instance)) {
            result += "Defined, ";
        }
        if (angular.isUndefined(instance)) {
            result += "Undefined, ";
        }
        if (angular.isObject(instance)) {
            result += "Object, ";
        }
        if (angular.isDate(instance)) {
            result += "Date ";
        }
        if (angular.isNumber(instance)) {
            result += "Number ";
        }
        if (angular.isString(instance)) {
            result += "String ";
        }
        if (angular.isFunction(instance)) {
            result += "Function ";
        }

        console.log("$scope: ", $scope);
        console.log("instanceType: " + result);
        return result;
    };

    // ON INIT - Date Pickers


/***************************** DATE PICKER - END   *****************************/

看起来你有两个选择:

1) 将所有日期转换为一致的格式。当您使用 REST API 时,将其转换为 UTC 格式,使其与本机日期选择器相同。

2) 在控制器中执行过滤(这要快得多,是推荐的方法)。

因此,例如,您可以有两个数组:

var originalBillingItems = []
var filteredBillingItems = []

然后在uib-datepicker-popup中你可以绑定一个函数到ng-change属性。例如

<input type="text" class="form-control" 
    uib-datepicker-popup 
    ng-model="search.lastBillDate" 
    ng-change="financeBillingCtrl.filterByDate()">

然后在控制器中你可以有一个函数

ctrl.filterByDate = function () {
    filteredBillingItemsArray = angular.copy(originalBillingItems)
    //filter however you want here
}

然后在 ng-repeat 中使用 filteredBillingItems 而不是 originalBillingItems。

这样做的好处是从摘要循环中删除了非常浪费的过滤,只有在列表非常小的情况下才推荐这样做。