Durandal小部件计时问题

时间:2013-09-24 15:29:05

标签: knockout.js durandal

据我所知,我的durandal(v1.2)小部件存在计时问题。

小部件用于多个视图,这适用于第一个视图。

所有其他视图保持禁用状态和公司()。长度保持为0。 代码在每个视图上执行,ajax调用成功完成,datacontext命中querySucceeded方法并填充传递的observableArray。

嵌入小部件:

<div data-bind="widget: { kind: 'companypicker', companyId: selectedCompanyId }"></div>

小部件标记:

<select data-bind="options: companies, optionsText: 'displayName', optionsValue: 'id', optionsCaption: 'Choose...', value: selectedCompany, enable: companies().length > 0"></select>

<span class="loader" data-bind="css: { active: companies().length == 0 }">
    <i class="icon-spinner icon-2x icon-spin"></i>
</span>

小部件代码:

define(function (require) {
    var ctor = function (element, settings) {
        var self = this;
        self.datacontext = require('services/datacontext');
        self.settings = settings;
        self.selectedCompany = ko.observable();
        self.companies = ko.observableArray();

        self.returningCompanyId = ko.observable(settings.companyId);

        settings.companyId.subscribe(function (newValue) {
            if (!newValue) {
                self.selectedCompany(null);
            }
        });

        self.selectedCompany.subscribe(function (newValue) {
            self.returningCompanyId()(newValue);
        });

        self.datacontext.getCompanies(self.companies);

    };

    return ctor;
});

这有一些奇怪的代码我不是很满意(返回,包装设置在observable等)但这使我能够传入一个observable(即'selectedCompanyId'),分配一个值并得到通知不使用pub / sub的当前视图的viewModel。

datacontext电话:

//datacontext construct obviously inspired by jpapa :)
var getCompanies = function (companies) {       
    var query = entityQuery.from('CompanyOverview');

    return manager.executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);

    function querySucceeded(data) {
        if (companies) {
            companies(data.results);
        }
        log('Successfully retrieved companies', data, true);
    }
};

如果我换行

self.datacontext.getCompanies(self.companies);

进入

setTimeout(function() {
    self.datacontext.getCompanies(self.companies);
}, 5000);

它适用于每一页。我现在的问题是,我无法理解这个时间问题的来源。

2 个答案:

答案 0 :(得分:1)

数据加载调用最好放在activate中。如果它是一个async call而不是Durandal 1.2,你必须在Durandal 2.0中返回一个承诺,你可以选择返回一个承诺,以便Durandal能够正确地进行构图。

因此,假设self.datacontext.getCompanies正在返回一个承诺,则以下内容应该足够了。

ctor.prototype.activate = function(){
    return self.datacontext.getCompanies(self.companies);
}

编辑正如评论中所指出的,上面的内容不适用于Durandal 1.2中的小部件。对于1.2中的普通视图,您仍然必须遵循该模式。

答案 1 :(得分:0)

您可以尝试在另一个事件中加载数据,而不是在构造函数中执行,

define(function (require) {
    var ctor = function (element, settings) {
        var self = this;
        self.datacontext = require('services/datacontext');
        self.settings = settings;
        self.selectedCompany = ko.observable();
        self.companies = ko.observableArray();

        self.returningCompanyId = ko.observable(settings.companyId);

        settings.companyId.subscribe(function (newValue) {
            if (!newValue) {
                self.selectedCompany(null);
            }
        });

        self.selectedCompany.subscribe(function (newValue) {
            self.returningCompanyId()(newValue);
        });


    };

    ctor.prototype.viewAttached=function(){
       this.datacontext.getCompanies(this.companies);
    }

    return ctor;
});

EDIT .. 尝试改变这样,

var getCompanies = function (companies) {       
    var query = entityQuery.from('CompanyOverview');

    return manager.executeQuery(query)



};

并在小部件中

 self.datacontext.getCompanies().then(function(data){
     if (companies) {
            companies(data.results);
        }
        log('Successfully retrieved companies', data, true);

  });