2

I'm using a datetimepicker directive that I'm having issues figuring out how to update the $modelValue.

// Parent Directive Controller

The parent controller just has a model object for use in child datepickers, which $watches for changes. Works fine if I type in the date directly, but datepicker sets the input value so have to tap into its onchange event.

controller: ['$scope', function( $scope ) {

        // Filter Date Range Model
        // NOTE: just sets the model object, possible values dateFrom: 'datestr' and dateTo: 'datestr'
        $scope.filterDateRange = {}; 

        /**
         * Watch for changes in the date picker model, and invoke
         * changes in the list results
         */
        $scope.$watch( function() {

            return $scope.filterDateRange;

        }, function( newDateRange, oldDateRange ) {

             // NOTE: never invoked except when the input is typed into directly
             console.log( "filterDateRange = ", $scope.filterDateRange )

             ... verbose code to update table results

        }, true);
}]

// DateRangePicker Markup

Simple input field with some params, a datepicker attribute directive, and ngModel set with parent model object and associated key.

<div class="form-group">
    <label for="dateFrom" class="control-label">Date From</label>
    <div class="input-group date">
        <span class="input-group-addon">
            <span class="fa fa-calendar"></span>
        </span>

        <input type="text" 
               class="form-control" 
               id="dateFrom" 
               name="dateFrom"  
               scope='min'
               match="dateTo"
               ng-model="filterDateRange['dateFrom']" // model and key
               date-range-picker>

        <span class="input-group-addon"
              ng-click="clearDate( 'dateFrom' )">
            <span class="fa fa-times"></span>
        </span>
    </div>
</div>

// DateRangePicker Directive

Date picker directive that creates the datepicker, registers with a service, and watches for an internal change.dp event. All of this works great except updating the model on datepicker change, so I've removed it since it bears no relevance to the question of how to set model value in parent so it can rerender my table results when the watch is triggered.

.directive('dateRangePicker', ['DateRangeService', 
    function( DateRangeService ) {

        return {
            restrict: 'AE',
            scope: {},
            require: 'ngModel',
            link: function( $scope, $element, $attrs, ngModelCtrl) {

                ... verbose code setting up datepicker

                // Watch for any changes to the datepicker date
                $element.on( 'change.dp', function( e ) {

                    ... verbose code handling datepicker response to event

                    // Set model value updating parent object???
                    // NOTE: at this point the input has a date string in it ie. 'Nov 6, 2014'
                    // Watch in parent not triggered since model not updated...

                    console.log($element.val()); // input value of 'Nov 6, 2014' or equiv

                    // ngModelCtrl.$setViewValue($element.val())
                    ngModelCtrl.$modelValue = $element.val();
                    // ngModelCtrl.$render();
                    // $scope.$apply();
                    // ngModelCtrl.$setValidity('match', $element.val());
                    // ngModelCtrl.$commitViewValue()

                });
            }
        };
}]);

1 Answer 1

1

Shouldn't set $modelValue directly, it won't propagate back to the actual model. Instead, use $setViewValue which will, amongst other things, update $modelValue for you. Wrap it in an apply because $setViewValue doesn't automatically trigger a digest.

$scope.$apply(function () {
    ngModelCtrl.$setViewValue($element.val());
    ngModelCtrl.$render();
});
Sign up to request clarification or add additional context in comments.

1 Comment

That works like a charm, thanks! I've only used $scope.$apply once before to get a GoogleChart directive to work, but I can't say I really understand its use, I'd never have figured this out. I actually tried $setViewValue and $render, but didn't give me anything, so like regular expressions I'll have to look into $scope.$apply and stop apparently avoiding it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.