Durandal干扰Knockout Bindings?

时间:2013-05-07 00:56:59

标签: knockout.js single-page-application durandal

我正在构建一个使用Durandal和Knockout的应用程序,当我使用durandal导航到我的SPA中的一个页面时似乎有问题。当我从主屏幕加载应用程序并导航到具有一系列级联下拉列表的第二页时,看起来好像绑定中断了。如果我刷新页面并加载第二页以开始绑定,所有似乎都按预期工作。除了现在的标题之外,第一页上没有任何内容,第二页有级联下拉列表。老实说,我不确定在这个问题上包含哪些代码,所以如果有什么人愿意,请随意询问。我正在使用'Knockout Context'Chrome插件窥视Knockout上下文,除了结果没有显示外,一切似乎都在工作。

有问题的简化视图模型

define(['services/logger',
    "services/datacontext"],
function (logger, datacontext) {
    var manufacturers = ko.observableArray();
    var manufacturer = ko.observable();
    var isSaving = ko.observable(false);
    var modelsWithSizes = ko.observableArray();

    manufacturer.subscribe(function (newValue) {
        datacontext.getBikeModelsWithSizes(modelsWithSizes, newValue.manufacturerID());
    });


    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);
        }
    };

    var canDeactivate = function () {
        if (hasChanges()) {
            var title = 'Do you want to leave ?';
            var msg = 'Navigate away and cancel your changes?';
            var checkAnswer = function (selectedOption) {
                if (selectedOption === 'Yes') {
                    cancel();
                }
                return selectedOption;
            };
            return app.showMessage(title, msg, ['Yes', 'No'])
                .then(checkAnswer);

        }
        return true;
    };

    var vm = {
        activate: activate,
        cancel: cancel,
        canDeactivate: canDeactivate,
        canSave: canSave,
        hasChanges: hasChanges,
        manu: manufacturer,
        manufacturers: manufacturers,
        modelsWithSizes: modelsWithSizes,
        save: save
    };

    return vm;

    //#region Internal Methods
    function activate() {
        manufacturers(datacontext.lookups.manufacturers),
        logger.log('Frames View Activated', null, 'frames', false);
        return true;
    }


    //#endregion
});

datacontext调用如下

datacontext.lookups = {
    manufacturers: function ()
    { return getLocal('Manufacturers', 'name', true); }
};

2 个答案:

答案 0 :(得分:0)

如果datacontext.lookups.manufacturers是预加载的observableArray,您可能需要将激活功能更改为:

function activate() {
    vm.manufacturers(datacontext.lookups.manufacturers());
    logger.log('Frames View Activated', null, 'frames', false);
    return true;
};

如果datacontext.lookups.manufacturers是对web api的异步调用,您需要将其更改为:

function activate() {
    logger.log('Frames View Activated', null, 'frames', false);
    return datacontext.lookups.manufacturers().then(querySuccess);

    function querySuccess(data)
    {
        vm.manufacturers(data.results);
    };
};

答案 1 :(得分:0)

我没有使用微风,所以我不知道getLocal()是否异步,但如果有疑问则返回包裹的$.when(syncOrAsync).then(...)

function activate() {
    var manufacturesPromise = datacontext.lookups.manufacturers();
    logger.log('Frames View Activated', null, 'frames', false);

    return $.when(manufacturesPromise).then(function(results){
       manufacturers(results);
    });
}