[英]Angular directive creation - using multiple templates
我是Angular JS的新手,我正在尝试创建一个datepicker指令。 它不会像Angular UI Bootstrap datepicker那样工作,因为它不会使用文本框,而是使用整页日历,您可以滑动并点击一天(这将更新ngModel)。
我的计划是有一个具有renderMonth()函数的指令。 此函数将接受一个月作为参数,并生成数组中的所有行/天,然后绑定到该月的模板。
我的问题是我可以在我的指令声明中为datepicker指定一个模板,但我不知道如何为行/天等指定模板并加载它们并绑定它们。 我可以使用jQuery和大量的字符串集合来做到这一点,但这似乎都是错的。
我一直在阅读Angular UI Datepicker的源代码,但作为一个新手,它对我来说没什么意义。 他们已将所有内容分解为许多子指令(月指令,年份指令等),并且他们有自己的模板,但这不是我想要做的,因为我的Angular技能不会延伸到创建与每个通信的指令其他。 Angular UI代码对我来说太复杂了。
我喜欢的一件事是他们在模板中使用现有的指令,如ng-repeat,并将它们绑定到数组或行/天。 对我来说,我需要在每次调用renderMonth()时加载模板并编译模板,因为它中有现有的指令。
所以,基本上我的问题是,是否有人有任何关于如何将模板导入我的渲染函数,编译它并将其绑定到我的指令范围内的行/日数据的示例。
我会说实话。 我不知道我是否说出任何意义。 我只是输入听起来模糊的话语。
我需要的是有人指出我正确的方向。 谢谢。
正如评论中所讨论的,我个人不会过分担心导入模板, $compile
函数或任何复杂的相对简单的标记。
我在这里创建了一个(非常)基本的准系统插件 ,以展示我的方法。 我用了moment.js来处理日期,因为我对vanilla javascript日期操作非常糟糕,并且发现它非常笨拙。
这是模板:
<div class="controls">
<button ng-click="prevMonth()"><-</button>
<span>{{selected.format('MMMM')}}</span>
<button ng-click="nextMonth()">-></button>
</div>
<div class="month">
<span class="day" ng-repeat="day in selected.days">
{{day.number}}
</span>
</div>
模板依赖于具有selected
属性的范围,该属性是时刻对象。 它所做的就是创建一些按钮来更改月份并在顶部显示月份名称,然后为该月的每一天创建一个跨度。
一小部分CSS将日期排成7行:
span.day{
float: left;
width: 25px;
}
span.day:nth-child(7n+1){
clear:left;
}
这是指令的link
功能:
link: function(scope, element, attributes){
// Set the selection to now initially.
scope.selected = moment();
generateDaysArray = function(){
// -- REMOVED FOR BREVITY -- //
return days;
}
// Watch the month for changes and update the days array
scope.$watch(
function(){
return scope.selected.month();
},
function(newVal, oldVal){
scope.selected.days = generateDaysArray();
}
)
// Control button actions
scope.nextMonth = function(){
scope.selected.add('month', 1)
}
scope.prevMonth = function(){
scope.selected.subtract('month', 1)
}
}
那里真的没有什么特别之处,但请注意所使用的$watch
命令利用了你可以传递一个函数而不是一个字符串的事实(尽管现在你可以使用'selected.month()'
作为一个串)。
如果你想将日期与一周中的几天对齐,那么生成days数组会稍微复杂一些,这是我开始做的,但没有完成。 我的计划是让数组中的每个对象都有一个isPreviousMonth
属性,该属性将使用ng-class
有条件地应用不同的样式,并且也会查找正确的数字,而不是仅使用~
作为偏移天数!
还有很多工作要做 - 关键是使日期可以选择并与ngModel
集成,但希望这个例子让你了解一种解决模板问题的方法。 还有很多其他方法可以做到这一点,但我发现这是最直观的。
延期
为了满足您对多个月的问题,我已经扩大了plunker一点。
我在指令中添加了一个属性:
<date-picker num-months="3"></date-picker>
并根据您在属性中指定的月数修改模板以ng-repeat
某些部分:
<div class="controls">
<button ng-click="prevMonth()"><-</button>
<span ng-repeat="month in months" class="month-title">
{{month.moment.format('MMMM')}}
</span>
<button ng-click="nextMonth()">-></button>
</div>
<div class="month" ng-repeat="month in months">
<span class="day" ng-repeat="day in month.days">
{{day.number}}
</span>
</div>
所以这需要一个月的数组,每个月都有2个属性:片刻和一系列天。 我添加了一些快速而又脏的javascript来生成它,但是我不会在这里粘贴它,因为几乎可以肯定有更简洁的方法!
请注意,目前我们仍在观察scope.selected
。选择月份中的更改,这将导致(可能不需要的)行为,如果您选择的日期不是在第一个月,日历将自行重新排列。 我认为在这种情况下不使用$watch
,我只是添加click事件来正确处理重绘日历。
PS这解决了克隆部分而不是滚动部分。 对于滚动,我建议在月份数组的任一端添加一个月,然后使用ng-show
条件,这意味着只显示中间月份。 然后,您可以利用angular的内置动画( 这是一个很好的参考 )来使用css滚动/滚出它们。 如果您想了解更多信息,请通过我为此问题打开的聊天与我联系。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.