0
votes

I'm been creating a web site following Hottowl's example. However, the value of hasChanges is not changed after saveChanges is called - even the data is actually saved in database table. I use hottowel durandal 2.0.1. I found the durandal version is different from the CCJS-Scratch example. Did I miss anything?

datacontext.js

    var manager = configureBreezeManager();
    var hasChanges = ko.observable(false);

    manager.hasChangesChanged.subscribe(function (eventArgs) {
        hasChanges(eventArgs.hasChanges); // The function isn't called when saveChanges is called
    });

    var cancelChanges = function () {
        manager.rejectChanges();
        log('Canceled changes', null, true);
    };

    var saveChanges = function () {
        return manager.saveChanges()
            .then(saveSucceeded)
            .fail(saveFailed);

        function saveSucceeded(saveResult) {
            log('Saved data successfully', saveResult, true);
        }

        function saveFailed(error) {
            var msg = 'Save failed: ' + getErrorMessages(error);
            logError(msg, error);
            error.message = msg;
            throw error;
        }
    };

The following code exist in the view model.

    var hasChanges = ko.computed(function () {
        return datacontext.hasChanges();
    });

    var cancel = function () {
        datacontext.cancelChanges();
    };

    var canSave = ko.computed(function () {
        return hasChanges() && !isSaving();
    });

    var save = function () {
        isSaving(true);
        return datacontext.saveChanges().fin(complete);

        function complete() {
            isSaving(false);
        }
    };
1

1 Answers

1
votes

Maybe you have a timing issue? You have a lot of nested observables and computed observables that I have trouble aligning at this late hour.

What I do know is that the Breeze DocCode:saveTodoTests.js show that hasChangesChanged is called with the correct eventArgs.hasChanges value when both saving changes and reverting (rejectChanges). Here is a passing test from that suite that confirms it.

test("hasChangesChanged event raised after saveChanges", 4, function () {
    var em = newTodosEm();    
    var hasChangesChangedRaised = [];
    em.hasChangesChanged.subscribe(
        function(eventArgs) {
            hasChangesChangedRaised.push(eventArgs.hasChanges);
        }
    );

    // add a Todo (and forget about it)
    em.createEntity('TodoItem',{ Description: "Learn to save in breeze" });

    stop();
    em.saveChanges()
       .then ( function() {
           equal(hasChangesChangedRaised.length, 2,
            "hasChangesChanged should have been raised twice");
           ok(hasChangesChangedRaised[0]===true,
            "first hasChangesChanged is true after create");
           ok(hasChangesChangedRaised[1]===false,
            "second hasChangesChanged is false after save");
           ok(!em.hasChanges(),
            "manager should not have pending changes after save");
        })
       .fail(handleSaveFailed)
       .fin(start);
});

Note that the hasChangesChanged event is raised twice in this test.

Please try debugging again and make sure that the event you're looking at is the one raised after the save, not during some other manipulation.

Also watch out for the nesting of KO events. Race conditions are possible.