使用ng-repeat,filter和uib-popup-datepicker过滤表列结果

时间:2017-01-16 22:33:52

标签: javascript angularjs html5 date angular-ui-bootstrap

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

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

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

输入字段ng-model

search.date

javascript对象

object.date

我相信我遇到的问题是html5输入类型的date元素返回的是一个JavaScript Date对象,格式如下:

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

我通过使用符合HAL的REST API获得的JSON结果采用以下格式:

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

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

以下是渲染后页面的屏幕截图,其后是HTML: enter image description here 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>

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

来显示对象的当前值):
enter image description here 

控制器代码:

/***************************** 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 个答案:

答案 0 :(得分:1)

看起来你有两个选择:

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。

这有利于从摘要周期中删除过滤,这非常浪费,仅在列表非常小的情况下才推荐使用。