2013-10-09 3 views
0

Я пытаюсь лениво загрузить сложный тип на ветру, но не могу понять, как это сделать.Breeze - Lazy load complex type

Причина, по которой я хотел бы использовать сложный тип, а не путь навигации, является службой, которую я должен потреблять, не делает CRUD так же, как ветер. Мне нужно отправить один объект со всеми его подобъектами (как скалярными, так и нескалярными) на один метод службы, ответственный за хранение данных (insert/update/delete).

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

Со сложными типами у меня нет этой проблемы (или нет, что я знаю).

я должен потреблять структуру объекта, как это:

1.Parent: продукт (класс)

1.1Child: пакеты (массив)

1.2Child: splitLevels (массив)

1.2.1Grandchild: права доступа (массив)

1.2.1.1Grandgrandchild: аптеки (массив)

1.2.2Grandchild: splitLevel (класс)

Пакеты загружаются вместе с продуктом, это работает отлично. Howevers, splitLevels не включены в этот файл данных (поскольку для этого требуется слишком много данных, и об этом часто не проконсультируются). При запросе этих данных к продукту добавляется логическое значение, чтобы указать, что они были загружены, и с этого момента необходимо отправить их и на сервер.

При загрузке продукта, это приводит к проблеме: Объект не поддерживает свойство или метод «GetProperty»

Это вызвано методом _initializeInstance в ветер:

if (initFn) { 
    if (typeof initFn === "string") { 
     initFn = instance[initFn]; 
    } 
    initFn(instance); 
} 
this.complexProperties && this.complexProperties.forEach(function (cp) { 
    var ctInstance = instance.getProperty(cp.name); 
    cp.dataType._initializeInstance(ctInstance); 
}); 

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

Есть ли способ обойти это? Есть ли способ использовать свойства навигации без получения нескольких объектов; так что я могу отправить один объект без использования этого:

if (product.entityAspect.entityState.isUnchanged()) { 
    product.entityAspect.setModified(); 
} 

// Packages 
var entitiesToSave = product.packages().slice();// copy 

// Split Levels 
if (product.storeSplitLevels) { 
    product.splitLevelsLoaded(true); 
    // TODO: Add split levels to entities to save 
} 

// Product Details 
entitiesToSave.push(product); 

ответ

0

Без дополнительной информации, я не совсем понятно, на что вы просите, но мы планируем добавить функцию к Breeze API для EntityManager, который будет позволяют вызывать произвольную конечную точку с произвольной структурой данных и иметь результат вызова, если таковой имеется, быть объединены обратно в EntityManager через JsonResultsAdapter.

До этого момента вы могли бы выполнить некоторые из этих действий прямо сейчас, минуя EntityManager.saveChanges и просто используя адаптер Aree Breeze непосредственно для вызова вашей конечной точки.Что-то вроде

var ajaxImpl = breeze.config.getAdapterInstance("ajax"); 
ajaxImpl.ajax({ 
     type: "POST", 
     url: url, 
     dataType: 'json', 
     contentType: "application/json", 
     data: bundle, // arbitrary data to server. 
     success: function (httpResponse) { 
      // perform custom client side code 
     }, 
     error: function (httpResponse) { 

     } 
    }); 
+0

К сожалению об этом, моих вопросах: 1. Можно ли ленивая нагрузку вложенных сложных типов; являющийся массивом, содержащим сложные типы, которые содержат другие сложные типы. Я не могу заставить это работать (cfr блок кода от бриза). 2. Если нет, существует ли способ использовать свойства навигации без наличия всех объектов на одном уровне, но так же, как их определяемый входной данные. Но вы ответили на этот вопрос своим комментарием. – Reinout

1

Я следил за вашим предложением создать пользовательский комплект.

Для других разработчиков, имеющих один и тот же вопрос, я сделал следующее:

  1. Создать пользовательскую функцию Unwrap, которая обеспечивает такую ​​же функциональность как функции UnWrap в ветерке, но распространив ее содержать навигационные свойства, Что ж.

  2. Добавить способ создания пакета сохранения из объекта.

Код:

function createEntitySaveBundle(entity) { 
    var rawEntity = unwrapInstance(entity); 
    var entities = []; 
    rawEntity.entityAspect = { 
     entityTypeName: entity.entityType.name, 
     defaultResourceName: entity.entityType.defaultResourceName, 
     entityState: entity.entityAspect.entityState.name, 
     autoGeneratedKey: { 
      propertyName: entity.entityType.keyProperties[0].nameOnServer, 
      autoGeneratedKeyType: entity.entityType.autoGeneratedKeyType.name 
     } 
    }; 
    entities.push(rawEntity); 

    return { entities: entities, saveOptions: {} }; 
} 

function unwrapInstance(entity) { 
    var rawObject = {}; 
    var stype = entity.entityType || entity.complexType; 
    var val; 
    var entities; 

    stype.dataProperties.forEach(function (dp) { 
     if (dp.isUnmapped) { 
      val = entity.getProperty(dp.name); 
      val = transformValue(val, dp, false); 
      if (val !== undefined) { 
       rawObject.__unmapped = rawObject.__unmapped || {}; 
       // no name on server for unmapped props 
       rawObject.__unmapped[dp.name] = val; 
      } 
     } else if (dp.isComplexProperty) { 
      if (dp.isScalar) { 
       rawObject[dp.nameOnServer] = unwrapInstance(entity.getProperty(dp.name)); 
      } else { 
       entities = entity.getProperty(dp.name); 
       rawObject[dp.nameOnServer] = entities.map(function (co) { return unwrapInstance(co); }); 
      } 
     } else if (dp.isDataProperty) { 
      val = entity.getProperty(dp.name); 
      val = transformValue(val, dp); 
      if (val !== undefined) { 
       rawObject[dp.nameOnServer] = val; 
      } 
     } 
    }); 

    stype.navigationProperties.forEach(function (np) { 
     if (np.isScalar) { 
      // Doesn't occur with products, enabling this results in an endless loop without checking if the navigation property already exists in the rawObject (recursive..) 
      // rawObject[np.nameOnServer] = unwrapInstance(entity.getProperty(np.name)); 
     } else { 
      entities = entity.getProperty(np.name); 
      rawObject[np.nameOnServer] = entities.map(function (eo) { return unwrapInstance(eo); }); 
     } 
    }); 

    return rawObject; 
} 
function transformValue(val, prop) { 
    if (prop.isUnmapped) return; 
    if (prop.dataType === breeze.DataType.DateTimeOffset) { 
     // The datajs lib tries to treat client dateTimes that are defined as DateTimeOffset on the server differently 
     // from other dateTimes. This fix compensates before the save. 
     val = val && new Date(val.getTime() - (val.getTimezoneOffset() * 60000)); 
    } else if (prop.dataType.quoteJsonOData) { 
     val = val != null ? val.toString() : val; 
    } 
    return val; 
}