Сделайте datepicker с angularjs (мои представления не обновляются)

Я хотел создать datepicker, используя jqueryUi и angularjs. Я хочу получить значение 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();
        })
    }
);

Дело в том, что когда я выбираю дату в моем средстве выбора даты, дата в «otherCtrl» или «DashboardDatePickerCtrl» не изменяется.

Я думал, что обновление значения атрибута моей фабрики обновит все другие переменные, указывающие на эту переменную.

Что я пропустил?

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


person Sebastien    schedule 11.07.2013    source источник
comment
не могли бы вы настроить скрипку   -  person Ajay Beniwal    schedule 11.07.2013
comment
В этом сообщении есть ответы - также проверьте комментарий @Mark Rajcock к нижнему ответу.   -  person rGil    schedule 11.07.2013
comment
Я обновил свой вопрос с помощью jsfiddle   -  person Sebastien    schedule 11.07.2013


Ответы (1)


Проблема в том, что вы теряете ссылку на свойство .from. Как только ваши otherController и DashboardDatePickerCtrl запускаются, они получают ссылку на selectedDate.from. Но в обработчике изменения даты вы меняете .from на другой объект в памяти (selectedDate.from = ...), но контроллеры по-прежнему указывают на старый, теперь потерянный в памяти навсегда (довольно драматично).

Самый простой способ исправить это - открыть в контроллере весь selectedDate и привязать его к его вспомогательному свойству. Таким образом вы измените .from, но не измените .selectedDate.

В вашем контроллере вы должны использовать $scope.date = selectedDate; вместо $scope.date = selectedDate.**from**, а в вашей привязке вы должны использовать date.from.format(...). Это решит проблему.

Если вы не возражаете, есть также календарная директива UI-Bootstrap.

Я немного рассказал об этом в этом ответе.

person Caio Cunha    schedule 11.07.2013
comment
Можно ли обновить мою скрипку? Я пытаюсь применить то, о чем вы говорите, но безуспешно ... Спасибо заранее - person Sebastien; 11.07.2013
comment
Еще один вопрос, как я могу наблюдать за изменением selectedDate в моих контроллерах из моей директивы datepicker ?. Когда мы нажимаем на следующий период, я хочу обновить входное значение моего datepicker. - person Sebastien; 11.07.2013
comment
Это сам по себе хороший вопрос. Я думаю, это хорошо обсудить это. Но поскольку вы изменяете внутреннее состояние объекта, а не саму ссылку на объект, возможно, лучшим вариантом будет не раскрывать объект selectedDate.from, а только предоставлять методы, которые будут добавлять (или вычитать) значения из объекта и отображать результат в некоторой переменной или отправка события, которое вы могли бы прослушать. Я найду время, чтобы подумать, и постараюсь ответить. А пока, если вы предложите хороший подход, пожалуйста, дайте мне знать. - person Caio Cunha; 12.07.2013