Knockout.js Durandal窗口小部件计时问题

Knockout.js Durandal窗口小部件计时问题,knockout.js,durandal,Knockout.js,Durandal,据推测,我的durandal(v1.2)小部件存在计时问题 该小部件用于多个视图,仅适用于第一个视图 所有其他视图保持禁用状态,并且company()。长度保持为0。 代码在每个视图上执行,ajax调用成功完成,datacontext命中querySucceeded方法并填充传递的observableArray 嵌入小部件: <div data-bind="widget: { kind: 'companypicker', companyId: selectedCompanyId }">

据推测,我的durandal(v1.2)小部件存在计时问题

该小部件用于多个视图,仅适用于第一个视图

所有其他视图保持禁用状态,并且company()。长度保持为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;
});
//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);
    }
};
这有一些看起来很奇怪的代码(返回、在observable中包装设置等),但这使我能够传入一个observable(即“selectedCompanyId”),分配一个值并在当前视图的viewModel中得到通知,而无需使用发布/订阅

数据上下文调用:

<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;
});
//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);
进入


它适用于每一页。我现在的问题是,我不明白这个计时问题是从哪里来的。

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

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;
});
编辑。。 试着像这样改变

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

  });

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

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;
});
编辑。。 试着像这样改变

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

  });

数据加载调用最好放在
激活
中。如果是
异步调用
而不是Durandal 1.2中的调用,则必须在Durandal 2.0中返回一个承诺,您可以选择返回一个承诺,以便Durandal能够正确地进行合成

因此,假设
self.datacontext.getcompanys
返回一个承诺,那么以下内容就足够了

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

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

数据加载调用最好放在
激活中。如果是
异步调用
而不是Durandal 1.2中的调用,则必须在Durandal 2.0中返回一个承诺,您可以选择返回一个承诺,以便Durandal能够正确地进行合成

因此,假设
self.datacontext.getcompanys
返回一个承诺,那么以下内容就足够了

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

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

您认为它不起作用是什么意思?什么不起作用?此外,您正在将公司放入构造函数中,您是想这样做,还是最好将它们传递到构造函数中,或者在对象完成构造后执行它们?正如我所提到的:对于第一个之后的所有视图,companys()。length保持为0,因此下拉列表保持禁用状态。在ctor中调用datacontext函数是否有问题?是否为视图组合设置了转换集,请尝试删除该转换集。(过渡:'entrence')哇,看起来这就是解决方案。现在没有时间问题,一切都很好!非常感谢,如果你把这个作为一个答案,我会接受的。你说它不起作用是什么意思?什么不起作用?此外,您正在将公司放入构造函数中,您是想这样做,还是最好将它们传递到构造函数中,或者在对象完成构造后执行它们?正如我所提到的:对于第一个之后的所有视图,companys()。length保持为0,因此下拉列表保持禁用状态。在ctor中调用datacontext函数是否有问题?是否为视图组合设置了转换集,请尝试删除该转换集。(过渡:'entrence')哇,看起来这就是解决方案。现在没有时间问题,一切都很好!非常感谢,如果你将此作为答案发布,我将接受它。这不起作用:(它-有时-导致一些视图工作,而不是只有一个,但有同样的时间问题,只是稍微好一点:)无论如何,谢谢!我增加了另一种方法。。试试看。同样的效果:(你的编辑也不起作用。仍然只有一个视图的公司()。长度>0这不起作用:(它-有时-导致一些视图工作,而不是只有一个,但有同样的时间问题,只是稍微好一点:)谢谢!我添加了另一种方法..试试看。同样的效果:(您的编辑也不起作用。仍然只有一个视图,其中公司().length>0我以前尝试过激活事件,但没有命中。但是viewAttached事件在1.2中命中了你的正确位置。小部件没有使用
activate
。我认为你的命中是由于时间问题,击倒太过急切地处理了可观察对象。这在2.0中得到了解决/解决。我以前尝试过激活事件,但它成功了未命中。但是viewAttached事件在1.2中命中了您的正确位置。小部件未使用
激活
。我认为,您的命中是由于时间问题导致的,该问题导致您过于急切地处理可观察对象。这在2.0中得到了解决/解决。