繁体   English   中英

角度指令创建 - 使用多个模板

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM