简体   繁体   中英

how to create an angular datepicker directive that uses ng-model

I have created an angular directive for my jQuery UI datepicker. The problem is that the directive doesn't update the input's ng-model when a date is selected. Any idea why?

http://jsbin.com/ufoqan/1/edit

AngularJS actually provides a special controller for interacting with ngModel that you can use inside your directives; just add require: 'ngModel' to your directive definition.

This gives you a fourth paramter to your link function, which is the controller you asked for in require --in this case, an instance of ngModelController . It has a method called $setViewValue you can use to set the value of the model:

app.directive('datepicker', function() {
  return {
    require: 'ngModel',
    link: function(scope, el, attr, ngModel) {
      $(el).datepicker({
        onSelect: function(dateText) {
          scope.$apply(function() {
            ngModel.$setViewValue(dateText);
          });
        }
      });
    }
  };
});

The beautiful thing about ngModelController is it automatically takes care of validation and formatting (in the case of a specific input type ) and integration with things like ngChange callbacks; check out this example : http://jsbin.com/ufoqan/6/edit

There may be a better way, but this will work:

http://jsbin.com/ufoqan/4/edit

app.directive('datepicker', function() {
  return {
    link: function(scope, el, attr) {
      $(el).datepicker({
        onSelect: function(dateText) {
          console.log(dateText);
          var expression = attr.ngModel + " = " + "'" + dateText + "'";
          scope.$apply(expression);
          console.log(scope.startDate);
          // how do i set this elements model property ?
        }
      });
    }
  };
});

You also asked why. The reason is that jquery happens outside the angular system. You can find more info here under the $apply method: docs

@Michelle Tilley and @Jonah are right about linking your directive to ngModel, but why you didn't use datePicker that is pure Angular instead of jQuery?
Well, i represent ADMdtp module. It's pure AngularJs dateTimePicker with lots of greate options:

  • completely synced with ngModel, so no need to destroy or manulay update dateTimePicker.
  • advance range picker; make as many dateTimePicker as you want related together, and again no need to destroy or manualy update each dateTimePicker.
  • disabing pattern; so easily you can disable any day(s) in week or month, like all weekends.
  • transition on changing days. (of curse you can disable it in options)
  • get full date details like date in UNIX format, Date format and year, month, day, hour and minute separately and ... by full-data attribute.
  • ...

<adm-dtp ng-model="date" full-data="date_full"></adm-dtp>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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