【问题标题】:Durandal interfering with Knockout Bindings?Durandal 干扰 Knockout Bindings?
【发布时间】:2013-04-30 20:19:34
【问题描述】:

我正在构建一个使用 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); }
};

【问题讨论】:

  • 您需要包含一些代码,例如“页面”视图模型模块,以及调用激活函数的代码
  • 我添加了更简单的有问题的视图模型。当您提到调用激活函数的东西时,您是在谈论带有 router.map 调用的 shell.js 吗?
  • 我很好奇“datacontext.lookups.manufacturers”是 ajax 还是异步调用?如果是这样,那让我很失望,因为您应该从激活调用中返回一个承诺。
  • 我添加了 datacontext 调用...这是一个 getLocal Breeze 调用,我认为它应该是同步的。

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


【解决方案1】:

我没有使用微风,所以我不知道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);
    });
}

【讨论】:

  • 这很有意义。但是当我实现它时,我的绑定仍然被破坏,我不知道为什么。
  • 您能模拟数据上下文请求并使用 OOTB Durandal 创建测试用例吗?这个 repo (github.com/dFiddle/dFiddle-1.2) 正在进行中,缺乏深入的文档,但它可能是生成可以在此处讨论的测试用例的最快方法。
  • OOTB?如果您认为这会有所帮助,我可以开始着手尝试重现该问题的小提琴。
  • 我已经推送了一个 repo @pltaylor.github.io/dFiddle-1.2 我刚刚开始尝试模拟数据上下文,并将继续对其进行填充,直到我可以让它运行为止。
  • Rainer-我已经模拟了数据上下文......并且我得到的错误与我在本地得到的不同。你想把这个对话从 SO 上转移到电子邮件或其他一些对话方式上吗?
【解决方案2】:

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

【讨论】:

  • 它是一个预加载的数组,我已经把它变成了一个函数并包含在原来的问题中。
  • 我的视图模型文件中缺少分号时遇到了一些问题。尽量确保所有函数都有一个结束分号。
猜你喜欢
  • 1970-01-01
  • 2014-04-27
  • 2013-08-16
  • 2013-03-02
  • 2015-02-09
  • 2012-07-17
  • 2019-06-17
  • 2015-02-12
  • 2011-04-02
相关资源
最近更新 更多