2013-09-24 3 views
1

У меня есть, предположительно, проблема времени с моим видовым дюрандалом (v1.2).Durandal widget timing issue

Виджет используется для нескольких видов, и это идеально подходит для первого взгляда.

все остальные виды остаются отключенными и компанией(). Длина остается 0. код выполнен на каждом представлении, аакс-вызовы завершены успешно, datacontext удаляет запрос. Метод suuccess и заполняет пройденный наблюдаемый массив.

вложение виджета:

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

т у него есть какой-то странный выглядящий код, я не очень доволен (возврат, обертывание в наблюдаемом и т. д.), но это позволило мне пройти в наблюдаемом (т. 'selectedCompanyId'), присвойте значение и получите уведомление в viewModel текущего представления без использования pub/sub.

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

он работает на каждой странице. моя проблема в том, что я просто не могу понять, откуда эта проблема времени.

+0

Что значит, что это не работает? Что не работает? Также вы получаете компании внутри конструктора, понимаете ли вы это, или было бы лучше передать их в конструктор или выполнить их после завершения построения объекта? –

+0

как я уже упоминал: для всех просмотров после первого, компании(). Длина остается 0, поэтому выпадающий список отключен. есть ли что-то неправильное в вызове функции datacontext в ctor? –

+1

У вас есть переходный набор для композиции вашего вида, попробуйте удалить это. (переход: 'entrence') –

ответ

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

    }); 
+0

это не работает :(он - иногда - приводит к тому, что некоторые виды работают вместо одного, но имеют одинаковую проблему с синхронизацией, просто немного лучше :) спасибо в любом случае! –

+0

Я добавил другой способ .. просто попробуйте. –

+0

такой же эффект :(ваше редактирование тоже не работает. Все еще только один вид, где компании(). Length> 0 –

1

Запросы на загрузку данных лучше всего разместить в activate. Если это async call, чем в Durandal 1.2, вам нужно возвратить обещание в Durandal 2.0, вы можете вернуть обещание, чтобы Дурандал мог правильно действовать с композицией.

Таким образом, если self.datacontext.getCompanies возвращает обещание, должно быть достаточно.

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

Редактировать Как было отмечено в комментарии вышеизложенное не будет работать для виджетов в Дюрандала 1.2.Для нормальных представлений в 1.2 вам все равно придется следовать этому шаблону.

+0

Я уже пробовал активировать событие, но оно не попадает, но событие viewAttached попадает в –

+1

. в 1.2 виджеты не использовали 'activate'. Я думаю, что ваш удар по проблеме с нокаутом, который слишком быстро уничтожает наблюдаемые. https://github.com/BlueSpire/Durandal/pull/207 Это решение/решено в 2.0. – RainerAtSpirit