2013-05-20 5 views
2

Разработчик Longtime .NET, создавший мое первое веб-приложение. Я пытаюсь использовать Durandal, Breeze и Knockout, которые, как я думаю, я понимаю в архитектуре. Однако это не меняет того факта, что я чувствую, что я просто приземлился в чужой стране с некоторыми из основных понятий jQuery.Я правильно использую Q с Дюрандалом, KO и Бриз?

У меня возникли проблемы с асинхронным программированием, используя понятие обещания, с Q. Обычно один будет иметь «активировать» обработчик Дюрандала в ViewModel KO с функцией, как,

var activate = function() { 
    return ebodatacontext.getOrganizations(organizations); 
}; 

где вызов выполняется для данных Breeze datacontext для получения данных от сущности над api, а «организации» - это ko.observableArray. В моем приложении это работает отлично.

Однако в моем случае мое мнение имеет два списка лиц, так что мне нужно два вызова DataContext, который я поставил вместе с Q, как это:

var activate = function() { 
    var promise = 
     Q.all([ 
      ebodatacontext.getOrganizations(organizations), 
      ebodatacontext.getUserRoles(userRoles) 
     ]); 
    return promise; 
}; 

Насколько я могу видеть, либо из тех, datacontext вызывает работу самостоятельно и привязывается к виду. Но когда я их так, только первый, похоже, работает. Боюсь, что у меня нет чего-то основного.

Я вижу в сетевом трафике, что оба вызова api сделаны для двух наборов сущностей. И хорошие результаты возвращаются по сети.

Однако, похоже, что ko.observable (userRoles) для второго вызова не содержит никаких данных. Если я поменяю их порядок, в массиве Q будет работать первый. Мне кажется, что я что-то забыл, и привязка происходит слишком рано или еще что-то.

Если мое использование Q здесь верно, я предполагаю, что у меня есть больше отладки, чтобы делать что-то в другом месте. Заранее спасибо.

Вот ebodatacontext с помощью Breeze:

define([ 
    'durandal/system', 
    'services/ebomodel', 
    'config', 
    'services/logger'], 
    function (system, ebomodel, config, logger) { 

     var EntityQuery = breeze.EntityQuery; 
     var manager = configureBreezeManager(); 
     var orderBy = ebomodel.orderBy; 
     var entityNames = ebomodel.entityNames; 

     var getOrganizations = function(organizationsObservable, forceRemote) { 
      if (!forceRemote) { 
       var p = getLocal('Organizations', orderBy.Name); 
       if (p.length > 0) { 
        organizationsObservable(p); 
        return Q.resolve(); 
       } 
      } 

      var query = EntityQuery.from('Organizations') 
       //.orderBy(orderBy.Name) 
       ; 

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

      function querySucceeded(data) { 
       if (organizationsObservable) { 
        organizationsObservable(data); 
       } 
       log('Retrieved [Organizations] from remote data source', 
        data, true); 
      } 
     }; 

     var getUserRoles = function(rolesObservable, forceRemote) { 
      if (!forceRemote) { 
       var p = getLocal('UserRoles', orderBy.Name); 
       if (p.length > 0) { 
        rolesObservable(p); 
        return Q.resolve(); 
       } 
      } 

      var query = EntityQuery.from('UserRoles') 
       // .orderBy(orderBy.Name) 
       ; 

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

      function querySucceeded(data) { 
       if (rolesObservable) { 
        rolesObservable(data); 
       } 
       log('Retrieved [UserRoles] from remote data source', 
        data, true); 
      } 
     }; 

     var cancelChanges = function() { 
      manager.rejectChanges(); 
      log('Canceled changes', null, true); 
     }; 

     var saveChanges = function() { 
      return manager.saveChanges() 
       .then(saveSucceeded) 
       .fail(saveFailed); 

      function saveSucceeded(saveResult) { 
       log('Saved data successfully', saveResult, true); 
      } 

      function saveFailed(error) { 
       var msg = 'Save failed: ' + error.message; 
       logError(msg, error); 
       error.message = msg; 
       throw error; 
      } 
     }; 

     var primeData = function() { 
     }; 

     var createOrganization = function() { 
      return manager.createEntity(entityNames.organization); 
     }; 

     var createUserRole = function() { 
      return manager.createEntity(entityNames.role); 
     }; 

     var hasChanges = ko.observable(false); 

     manager.hasChangesChanged.subscribe(function(eventArgs) { 
      hasChanges(eventArgs.hasChanges); 
     }); 

     var ebodatacontext = { 
      createOrganization: createOrganization, 
      createUserRole: createUserRole, 
      getOrganizations: getOrganizations, 
      getUserRoles: getUserRoles, 
      hasChanges: hasChanges, 
      primeData: primeData, 
      cancelChanges: cancelChanges, 
      saveChanges: saveChanges 
     }; 

     return ebodatacontext; 

     //#region Internal methods   

     function getLocal(resource, ordering, includeNullos) { 
      var query = EntityQuery.from(resource) 
//    .orderBy(ordering) 
       ; 
      //if (!includeNullos) { 
      // query = query.where('id', '!=', 0); 
      //} 
      return manager.executeQueryLocally(query); 
     } 

     function queryFailed(error) { 
      var msg = 'Error retreiving data. ' + error.message; 
      logger.logError(msg, error, system.getModuleId(ebodatacontext), true); 
      throw error; 
     } 

     function configureBreezeManager() { 
      breeze.NamingConvention.camelCase.setAsDefault(); 
      var mgr = new breeze.EntityManager(config.eboRemoteServiceName); 
      ebomodel.configureMetadataStore(mgr.metadataStore); 
      return mgr; 
     } 

     function log(msg, data, showToast) { 
      logger.log(msg, data, system.getModuleId(ebodatacontext), showToast); 
     } 
     //#endregion 
}); 
+1

Ваш Q-вызов выглядит правильно. Получают ли методы 'get' результаты или обещания? – Tyrsius

+0

Как подразумевает @Tyrsius, это помогло бы нам, если бы мы лучше поняли, что такое возвращаемое значение ваших функций getOrganizations и getUserRoles. Если мы увидим пример, который бы очень помог ... в его нынешнем виде у нас не так много возможностей. – GotDibbs

+0

Я добавил код ebocontext. Спасибо всем за помощь. –

ответ

1

я отвечаю на мой собственный вопрос, потому что я был путь от основы, думая, что проблема была из-за Q и обещаний. Кажется, я работал нормально.

Все мои проблемы были решены, осознав, что в потоковом тексте Breeze мне нужно инициализировать переданный ko.observableArray с data.result вместо данных.

Мой сломанный код:

var getOrganizations = function (organizationsObservable) { 

     var query = EntityQuery.from('Organizations'); 

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

     function querySucceeded(data) { 
      if (organizationsObservable) { 
       organizationsObservable(data); 
      } 
      log('Retrieved [Organizations] from remote data source', 
       data, true); 
     } 
    }; 

Мой код, который работает:

var getOrganizations = function (organizationsObservable) { 

     var query = EntityQuery.from('Organizations'); 

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

     function querySucceeded(data) { 
      if (organizationsObservable) { 
       organizationsObservable(data.results); 
      } 
      log('Retrieved [Organizations] from remote data source', 
       data, true); 
     } 
    }; 

Если вы, как новичок в этом, как я, разгадка в том, что когда вы наблюдаете содержимое возвращающийся ko.observableArray не должен быть единственным объектом типа XHR (uh duh). XHR, который возвращается от вызова API к контроллеру, имеет фактическую дату в поле «результат».

Спасибо всем за то, что вы с новичком пытались использовать все новейшие технологии для клиентских приложений SPA.

Хорошая новость заключается в том, что, хотя я все еще несколько не знаю, что касается некоторых основ, я хорошо нахожусь на пути к тому, чтобы иметь богатого клиента с полным жизненным циклом данных и навигацией, который выглядит как профессиональный сайт (благодаря загрузке) ,

Я хотел бы рассказать о планах Джона Папы Pluralsight и статье в блоге о приложениях SPA с его шаблоном Hot Towel.

http://www.johnpapa.net/hottowel/