出生日期 - 过滤日期取决于月份

时间:2014-08-19 10:36:41

标签: angularjs angularjs-directive angularjs-scope angularjs-filter

我目前正在制作出生日期的一天下拉列表,此字段中的值取决于所选的月份。我现在有这个工作,如下所示,但我想将逻辑移动到控制器或过滤器,而不是将其留在html文件中。

 <select  name="personal_dob_day" ng-model="dob_day">                 
                <option>1</option>
                <option>2</option>
                <option>3</option>
                <option>4</option>
                <option>5</option>
                <option>6</option>
                <option>7</option>
                <option>8</option>
                <option>9</option>
                <option>10</option>
                <option>11</option>
                <option>12</option>
                <option>13</option>
                <option>14</option>
                <option>15</option>
                <option>16</option>
                <option>17</option>
                <option>18</option>
                <option>19</option>
                <option>20</option>
                <option>21</option>
                <option>22</option>
                <option>23</option>
                <option>24</option>
                <option>25</option>
                <option>26</option>
                <option>27</option>
                <option>28</option>
                <option ng-if=" dob_month != 'February' || !( dob_year % 4)")>
                    29
                </option>
                <option ng-if=" dob_month != 'February'">
                    30
                </option>
                <option ng-if=" dob_month == 'January' || dob_month == 'March' || dob_month == 'May' || dob_month == 'July' || dob_month == 'August' || dob_month == 'October' || dob_month == 'December'">
                    31
                </option>
 </select>

我想要做的是在控制器中创建一个数组:

   var dayRange = [];
    for(var i=1;i<=31;i++) {
      dayRange.push(i);
    }
    $scope.days = dayRange;

并使用ng-options循环遍历:

<select  ng-options="day for day in days track by day" name="personal_dob_day" ng-model="dob_day" >

我在想,如果我这样做是否可以实现某种类型的过滤器,它会检查月份模型的值,并且只显示下拉天数中的相应日期?如果是这样,我将如何创建这样的过滤器,因为我对它们的体验是有限的。或者也许还有一个更好的方式来解决这个问题?

非常感谢任何有关此事的帮助。

感谢。

2 个答案:

答案 0 :(得分:6)

您应该考虑使用ng-options指令传入一个表达式,该表达式从控制器模型中的数组中提取标签。

首先构建将保存数年,月和日的数组的控制器。在$ scope对象上创建属性,以便可以通过视图上的ng-options指令访问这些数组。

如果将JQuery包含为依赖项,则可以通过以下方式构建数组:

var years = $.map($(Array(numberOfYears)), function (val, i) { return i + 1900; });
var months = $.map($(Array(12)), function (val, i) { return i + 1; });
var days = $.map($(Array(31)), function (val, i) { return i + 1; });

如果您不想拥有JQuery依赖项,只需为所有三个数组使用一个好的旧for循环。以下代码将为您提供数组$ scope的访问器:

$scope.Years = years;
$scope.Months = months;
$scope.Days = days;

返回HTML视图,添加带有ng-options和ng-model ng-options指令的select元素,例如:

<div class="ng-scope" ng-controller="BirthdayController">
<select ng-model="SelectedYear" ng-options="label for label in Years"></select> 
<select ng-model="SelectedMonth" ng-options="label for label in Months"></select> 
<select ng-model="SelectedDays" ng-options="label for label in Days"></select>
</div>

我假设您熟悉创建AngularJS模块并向其添加控制器,以及向容器添加必要的ng-app指令,ng-scope类和ng-controller指令。到目前为止,您将有三个下拉列表,其中包含年份列表,12个月的列表和31天的列表。如果你想有一个受抚养日列表继续阅读! :)

有关基本版本,请参阅此plnkr:http://plnkr.co/edit/VfEpwPv084H7XiifEsnm?p=preview

奖金回合:

您可以更进一步,让日期列表显示正确的天数,因为天数确实依赖于所选的月份和年份。 2月在非闰年上有28天,在闰年上有29天。其他月份有30天或31天,具体取决于月份。如果你想要充满想象力,你需要控制器中的一个功能来确定闰年,并确定返回多少天来计算一年是否是javascript中的闰年,以下功能非常有用:

var isLeapYear = function (selectedYear) {
var year = SelectedYear || 0;
return ((year % 400 == 0 || year % 100 != 0) && (year % 4 == 0)) ? 1 : 0;}

虽然使用Angular看起来会略有不同,因为$ scope已经包含selectedYear并且不必传入.isLeapYear辅助函数由另一个函数访问,该函数确定给定月份显示的天数年份组合如下:

var getNumberOfDaysInMonth = function (selectedMonth) {
var selectedMonth = selectedMonth || 0;
return 31 - ((selectedMonth === 2) ? (3 - isLeapYear()) : ((selectedMonth - 1) % 7 % 2));}

现在,所有需要在原始select元素上完成的日子都是在ng-options指令上添加一个limitTo过滤器来改变实际呈现的元素数量。月份和年份的选择元素需要ng-Change指令,因此我们可以更新$ scope上的字段,该字段将保留数字以限制天数。

<select ng-model="SelectedYear" ng-options="label for label in Years" ng-change="UpdateNumberOfDays()"></select> 
<select ng-model="SelectedMonth" ng-options="label for label in Months" ng-change="UpdateNumberOfDays()"></select> 
<select ng-model="SelectedDays" ng-options="label for label in Days | limitTo:NumberOfDays"></select>

在控制器$ scope.UpdateNumberOfDays()的函数中填充NumberOfDays,当然这将使用上面描述的辅助函数GetNumberOfDaysInMonth。

另外一个额外的好处是智能版本的plnkr:http://plnkr.co/edit/AENh6Ynj4kNKZfLsXx4N?p=preview

享受!

答案 1 :(得分:0)

尝试:

<select>
    <option ng-repeat="day in days">{{day}}</option>
</select>