使用angularjs制作一个日期选择器(我的视图未更新)

时间:2013-07-11 11:24:35

标签: angularjs angularjs-directive angularjs-scope

我想使用jqueryUi和angularjs创建一个datepicker。我想从我的所有控制器中获取datepicker值。为此,我创建了一个工厂:

App.factory "selectedDate", ['$rootScope', ($rootScope) ->
  selectedDates = {}
  selectedDates.from = moment()

  selectedDates.nextPeriod = ->
    this.from.add('days', 1);

  selectedDates.previousPeriod = ->
    this.from.subtract('days', 1);

  return selectedDates
]

我的控制员:

App.controller "DashboardDatePickerCtrl", ['$scope', 'selectedDate', ($scope,selectedDate) ->

  $scope.nextPeriod = () ->
    selectedDate.nextPeriod()

  $scope.previousPeriod = () ->
    selectedDate.previousPeriod()

  $scope.date = selectedDate.from
]

App.controller "otherCtrl", ['$scope', 'selectedDate', ($scope,selectedDate) ->
  $scope.date = selectedDate.from
]

我的html(haml):

.row-fluid{ "ng-controller" => "DashboardDatePickerCtrl" }
  .span4.offset5
    %span.fui-arrow-left.right10.top5.font-large.pointer{ "ng-click" => "previousPeriod()"}
    .control-group.inline
      .input-prepend.input-datepicker
        %button.btn{:type => "button"}
          %span.fui-calendar
        %input#datepicker-01.span2{:type => "text", "ng-model" =>"date", "datepicker" => ""}

    {{ date }}

    %span.fui-arrow-right.left10.font-large.pointer{ "ng-click" => "nextPeriod()"}

  .span3
    .btn-group.choose-granularity{"data-toggle" => "buttons-radio"}
      %button#by_4h.btn.btn-primary.one_month One month
      %button#by_1h.btn.btn-primary.one_week One week
      %button#by_5m.btn.btn-primary.one_day.active One day

.row-fluid
  .span12{ "ng-controller" => "otherCtrl" }
    %h6 An other ng controller
    %p
      {{ date.format("DD MMM, YYYY") }}

完成后,我的datepicker指令:

App.directive('datepicker', (selectedDate) ->
  return {
    restrict: 'A'
    require : 'ngModel'
    link : (scope, element, attrs, ngModelCtrl) ->
      $ ->
        element.datepicker({
          showOtherMonths: true
          selectOtherMonths: true
          dateFormat: "d MM, yy"
          yearRange: '-1:+1'
          onSelect: (date) ->
            selectedDate.from = moment(date)
            scope.$apply();
        })
    }
);

事实是,当我在datepicker中选择日期时,“otherCtrl”或“DashboardDatePickerCtrl”上的日期不会改变。

我认为更新工厂属性的值会更新指向此变量的所有其他变量。

我错过了什么?

JSFIDDLE: http://jsfiddle.net/9HZdm/6/

1 个答案:

答案 0 :(得分:2)

问题是您丢失了对.from属性的引用。只要您的otherControllerDashboardDatePickerCtrl启动,他们就会获得对selectedDate.from的引用。但是在你的日期更改处理程序中,你正在将.from更改为内存中的另一个对象(selectedDate.from = ...),但是控制器仍然指向旧的控制器,现在永远丢失在内存中(相当戏剧性)

修复它的简单方法是在控制器中公开整个selectedDate,并绑定到其子属性。这样,您将更改.from,但不会更改.selectedDate

在您的控制器中,您应该使用$scope.date = selectedDate;而不是$scope.date = selectedDate.**from**,并且在绑定中,您应该date.from.format(...)。这将解决问题。

如果您提出建议,还有UI-Bootstrap calendar directive

我在this answer处谈了一点。