0

I am using Durandal 2.1, and I am having a problem with view composition. I have a view for managing many types of items. I also want a view to manage a subset of those types. So I created a manage view and a managesubset view. The managesubset view just composes the manage view and passes it an array containing the subset of items. This way the user can go to /100/manage or 100/managesubset where managesubset will only allow the user to manage a subset of items. I am using this pattern because I will have multiple different versions of managesubset.

My problem is that the canDeactivate method is not fired when going to managesubset. Is there anyway to fire the canDeactivate and Deactivate lifecycle events when composing?

According to #3 under Activator Lifecycle Callbacks here, I should be able to do this, but I cannot find any good examples.

Code:

manage.js

define(['durandal/app', 'plugins/router'], function (app, router) {
    var constructor = function () {
        var self = this;
        //...variable creation and assignment

        //life cycle events
        self.activate = function (viewmodel) {
            self.recordId(viewmodel.recordId);
            self.assignableTypes(viewmodel.assignableTypes);
            self.pageHeaderTitle = viewmodel.pageHeaderTitle;
            self.pageHeaderIcon = viewmodel.pageHeaderIcon;
        };

        self.canActivate = function (id) {
            var deferred = $.Deferred();

            //check if user has access to manage equipment

        };

        self.canDeactivate = function () {
            if (!self.saveSuccessfull() && this.isDirty()) {
                return app.showMessage("You have unsaved changes, are you sure you want to leave?", "Unsaved Changes", ["Yes", "No"]);
            }
            else {
                return true;
            }
        }
    };

    return constructor;
});

managesubset.js

 define([], function () {
    var recordId = ko.observable();
    var manageRecord = ko.observable();

    return {
        recordId: recordId,
        manageRecord: manageRecord,
        activate: function (id) {
            recordId(id);
            manageRecord({
                pageHeaderTitle: 'Manage Subset',
                pageHeaderIcon: 'cb-subset',
                assignableTypes: [102],
                recordId: recordId()
            });
        },
        canActivate: function (id) {
            var deferred = $.Deferred();

            //check if user has access to manage equipment
        }
    }
});

managesubset.html

 <div data-bind="compose: { model: 'manage', activationData: manageRecord() }"></div>

The activate is called correctly each time. The deactivate and canDeactive are what don't work, and they are never called.

Zach Green
  • 3,421
  • 4
  • 29
  • 32
  • possible duplicate of [Durandal Compose: activate method not always called](http://stackoverflow.com/questions/29829429/durandal-compose-activate-method-not-always-called) please let me know if this solves your issue – Matthew James Davis Apr 28 '15 at 18:27
  • not really. the activate is called correctly each time. the deactivate and canDeactive are what don't work, and they are never called. the child router option could work, but that seems like overkill. – Zach Green Apr 28 '15 at 18:37
  • Are there any errors in the Console window of the browser? – Nathan Fisher May 07 '15 at 00:59
  • No. It seems that canDeactivate and Deactivate are not part of the composition lifecycle, and cannot be made to be part of the lifecycle. – Zach Green May 07 '15 at 12:05
  • What are you setting `app.setRoot()` to in your main module file? – Brett Jun 16 '15 at 21:02
  • hi @Zach, were you able to fix this? I am also facing the same – Habib Oct 29 '15 at 12:31
  • No. I don't remember exactly, but I am pretty sure I changed how I was doing things to avoid needing the canDeactivate in composed models – Zach Green Oct 29 '15 at 13:05

0 Answers0