javascript - 为什么在 durandaljs 中不调用 compositionComplete 事件

标签 javascript durandal

那是我的示例项目 (8,3 MB) Visual Studio 2012 解决方案:

sample project zipped

我的问题:

模块 step2 及其 compositionComplete 事件未被调用! 模块 step1 是并且相同的事件工作正常!

这样你就可以重现问题:

1.) 启动应用

2.) 点击“浏览学年”按钮

3.) 单击“创建”按钮(打开 SchoolyearWizard)

4.) 向导步骤 1 可见,调用其 compositionComplete 事件

5.) 点击“下一步”按钮

6.) 向导步骤 2 是可见的,它的 compositionComplete 事件未被调用

我只在这里发布重要的内容,这些是 5 个模块。

  • SchoolyearDialog 模块由SchoolyearBrowser 和SchoolyearWizard 模块组成。两个模块都通过“compose: activeScreen”绑定(bind)进行切换。
  • 当加载 SchooleyearWizard 并且用户单击下一步按钮加载第 2 步时,这就是问题所在,请参见上面的第 6 条。

SchoolyearDialog

define(['durandal/app','plugins/dialog', 'knockout', 'services/dataservice', 'plugins/router', 'moment'], function (app, dialog, ko, dataservice, router, moment) {

    var SchoolyearDialog = function () {

        var self = this;
        self.activeScreen = ko.observable('viewmodels/SchoolyearBrowser'); // set the schoolyear browser as default module 

        app.on('activateStep1').then(function (obj) {
            self.activeScreen(obj.moduleId);
        });

        app.on('activateStep2').then(function (obj) {          
            self.activeScreen(obj.moduleId);
        });

        app.on('dialog:close').then(function (options) {

            dialog.close(self, options );
        });

        self.closeDialog = function () {            
            dialog.close(self, { isSuccess: false });
        }
    }

    SchoolyearDialog.show = function () {

        return dialog.show(new SchoolyearDialog());
    };   

    return SchoolyearDialog;
});

学年浏览器

define(['durandal/app', 'plugins/dialog', 'knockout', 'services/dataservice', 'plugins/router', 'moment'],
    function (app, dialog, ko, dataservice, router, moment) {
        var SchoolyearBrowser = function () {
            var self = this;

            self.create = function () {
                app.trigger('activateStep1', {
                    moduleId: 'viewmodels/SchoolyearWizard',
                    viewMode: 'create'
                });
            }

            self.open = function () {
                // do not open the wizard
            }

            self.compositionComplete = function (view) {
                debugger;
            }
        };
        return SchoolyearBrowser;
    });

SchoolyearWizard

define(['durandal/activator', 'viewmodels/step1', 'viewmodels/step2', 'knockout', 'plugins/dialog','durandal/app'], function (activator, Step1, Step2, ko, dialog, app) {

    var steps = [new Step1(), new Step2()];
    var step = ko.observable(0);   // Start with first step

    var activeStep = activator.create();

    var stepsLength = steps.length;

    var hasPrevious = ko.computed(function () {
        return step() > 0;
    });

    var caption = ko.computed(function () {

        if (step() === stepsLength - 1) {            
            return 'save';
        }
        else if (step() < stepsLength) {
            return 'next';
        }
    });

    activeStep(steps[step()]);

    var hasNext = ko.computed(function () {
        if ((step() === stepsLength - 1) && activeStep().isValid()) {
            // save
            return true;
        } else if ((step() < stepsLength - 1) && activeStep().isValid()) {

            return true;
        }
    });

    return {
        showCodeUrl: true,
        steps: steps,
        step: step,
        activeStep: activeStep,
        next: next,
        caption: caption,
        previous: previous,
        hasPrevious: hasPrevious,
        hasNext: hasNext
    };

    function isLastStep() {
        return step() === stepsLength - 1;
    }

    function next() {

        if (isLastStep()) {

            // Corrects the button caption when the user re-visits the wizard
            step(step() - 1);
            // Resets the wizard init page to the first step when the user re-visits the wizard
            activeStep(steps[0]); 
            debugger;
            // save;

        }
        else if (step() < stepsLength) {
            step(step() + 1);
            activeStep(steps[step()]);
            debugger;
            //app.trigger('activateStep2', {
            //    moduleId: 'viewmodels/step2'
            //});
        }
    }

    function previous() {
        if (step() > 0) {
            step(step() - 1);
            activeStep(steps[step()]);
        }
    }
});

第一步

define(function () {
    return function () {
        var self = this;

        self.isValid = function () {
            return true;
        }
        self.name = 'step1';

        self.compositionComplete = function (view) {
            debugger;            
        }
    };
});

第二步

define(function () {
    return function () {

        this.isValid = function () {
            return true;
        }
        this.name = 'step2';

        self.compositionComplete = function (view) {

           // I never get here WHY ???            
        }
    };
});

最佳答案

在第 2 步中,您没有 self.compositionCompleted 事件,因为您没有上下文“self”

你需要声明self = this;

var self =this;
self.name = whatever;
self.compositionComplete

关于javascript - 为什么在 durandaljs 中不调用 compositionComplete 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18751101/

相关文章:

php - 从 json 返回多个值

javascript - Durandal js路由器设置

knockout.js - 单元测试 View 模型并模拟依赖项

javascript - 在 Knockout 中更改可观察值的值时进行动画处理

durandal - 如何在使用 Durandal 的 route 使用图标?

javascript - 在 Fancybox knockout 后重新应用绑定(bind)

javascript - Jasmine 中使用外部库进行单元测试

javascript - 服务器返回空响应

javascript - 如何动态地将 ng-repeat 属性添加到元素

javascript - 保护javascript中的全局引用