afr0
afr0

Reputation: 888

asp.net mvc spa durandaljs date format not working with Knockout

I'm exploring durandaljs for asp.net mvc SPA. I'm using APS.net MVC4, Durandaljs, Knockoutjs, breeze, moment and other libs found under hottowel SPA sample.

I have a client view which is bound with DOB, DateTime.

    <td colspan="2">
                    <span id="dob" data-bind="text: DOB"></span>
            </td>                                                

and my ViewModel contains code

    vm.studentProfile().DOB(moment(vm.studentProfile().DOB()).format('L'));
        logger.log(vm.studentProfile().DOB(), null, system.getModuleId(vm), false);

Above code actually comes from querySucceeded. i.e

    return manager
        .executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);

This supposed to be working as I've achieved this already for some other fields but in case of DateTime KnockoutOut doesn't update GUI whereas I can see the UPDATED format date in console log. Can somebody tell me what am I missing here. thanks in advance.

Upvotes: 2

Views: 445

Answers (2)

PlTaylor
PlTaylor

Reputation: 7525

What about just making a ko.Computed like the following

vm.studentProfileFormatted = ko.computed({
  read: function () {
    return moment(vm.studentProfile().DOB()).calendar();
  },
  write: function (value) {
    var time = moment(value, "MM-DD-YYYY").toJSON();
      vm.studentProfile(time);
  },
  owner: vm
});

And then calling studentProfileFormatted in your view.

Upvotes: 0

Jalayn
Jalayn

Reputation: 9284

The problem may lie with the fact that DOB is a MomentJs date, not a JavaScript Date or string. You most likely need to add a custom binding handler for displaying these dates, such as for example:

ko.bindingHandlers.moment = {
            update: function(element, valueAccessor) {
                var value = valueAccessor();
                var formattedValue = ko.utils.unwrapObservable(value).format('LLLL');
                $(element).text(formattedValue);
            }
};

Now, instead of using the "text" binding handler, use the "moment" binding handler like this:

<span id="dob" data-bind="moment: DOB"></span>

Edit: added an example of adding custom plugins using AMD modules with RequireJS:

require(['jquery', 'json2', 'sammy', 'amplify', 'bootstrap', 'moment', 'toastr', 'showdown', 'markdowneditor', 'spin'], 
        function($){

        // Require that plugins be loaded, after the prerequisite libraries
        //       We load the plugins here and now so that we don't have to 
        //       name them specifically in the modules that use them because
        //       we don't want those modules to know that they use plugins.
        requirejs([
                'jquery.ui',                // jquery plugin
                'jquery.mockjson',          // jquery plugin
                'jquery.tmpl',          // jquery plugin
            ], 
            function () { 
                require(['ko'],
                    function(ko) {
                        // ensure KO is in the global namespace ('this') 
                        if (!this.ko) {
                            this.ko = ko;
                        };

                        requirejs([
                                'libs/knockout.binding.handlers',       // Knockout custom binding handlers
                                'libs/knockout.extenders',       // Knockout custom binding handlers
                                'libs/bootstrap.extenders',       // Knockout custom binding handlers
                            ],
                            // Plugins generally don't return module objects
                            // so there would be point in passing parameters to the function
                            function () { 
                                require(['app'], function(App) {
                                    App.initialize(); 
                                });
                            }
                        );
                    }
                );
            }
        );
    }
);

Upvotes: 1

Related Questions