2013-05-08 3 views
0

У меня возникли проблемы с сохранением обновлений существующего графика данных в Breezejs с использованием привязок Knockoutjs.Связывание Breeze + Knockout в коллекциях графов

Я начал с SPA-отеля John Papa, используя HotTowel & Durandal.

Признаки того, что я могу сохранить обновления в записи врача, если обновление является простым свойством врача. Однако, если я добавлю новый элемент в одну из коллекций, содержащихся в лекаре, я могу сохранить элемент коллекции, но он попадает на сервер и сохраняется в базе данных, но с нулевыми свойствами и без ссылки на врача. Я использую Specialty в качестве примера, но я вижу то же поведение с любой коллекцией в записи Physician, к которой я добавляю элемент. Добавленный элемент подходит к серверу с нулями во всех свойствах.

График врача отображается на странице хорошо, и я могу связать выпадающие списки с соответствующими значениями для конкретных полей, где это необходимо. Флажки и т. Д. Также показывают соответствующие значения.

Вот сегмент HTML, который я использую:

<div id="physGraph" class="span10" data-bind="with: currentPhysician()[0]"> 
    <!-- more stuff here --> 
    <div id="physSpecialties" class="span8"> 
     <span class="span8">Physician Specialties<i class="icon-plus-sign" title="Add new specialty to physician" data-bind="click: $parents[0].addSpecialtyToPhysician"></i></span> 
     <div class="span8 table-bordered" data-bind="foreach: physicianSpecialties"> 
     <div class="span8"> 
      <span data-bind="text: specialty().name()"></span> 
     </div> 
     <div class="span7 table-bordered"> 
      <i class="icon-remove-sign" title="Remove specialty from physician list" data-bind="click: $parents[1].removeSpecialtyFromPhysician"></i> 
      <select data-bind="options: $parents[1].specialties(), optionsText: 'name', value: specialty()"></select> 
     </div> 
     </div> 
    </div> 
    <!-- more stuff here --> 
</div> <!-- end with: currentPhysician()[0] 

Вот как я получаю врача:

define([services/datacontext', 'viewmodels/physList'], function (datacontext, physListVm) { 
    var initialized = false; 
    var physNotes = ko.observableArray(); 
    var currentPhysician = ko.observable(); 
    var vm = { 
    activate: activate, 
    title: 'Physician Edit', 
    currentPhysician: currentPhysician, 
    addSpecialtyToPhysician: addSpecialtyToPhysician, 
    save: save, 
    // more code in here 
    } 

    // internal functions for physDetailEdit 
    function activate() { 
    initLookups(); 
    var physIdSelectedFromList = physListVm.selectedPhys().id(); 
    return getPhysicianDetail(physIdSelectedFromList); 
    } 

    function getPhysicianDetail(requestedPhysId) { 
    var promise = datacontext.getPhysicianDetails(requestedPhysId, currentPhysician); 
    return promise; 
    } 
    more code in here 
} 

Вот как я добавляю по специальности:

function addSpecialtyToPhysician(item, event) { 
    var newItem = datacontext.createSpecialty(); 
    item.physicianSpecialties.push(newItem); 
    // I've also tried it like this -- > currentPhysician()[0].physicianSpecialties.push(newItem); 
    } 

Вот как я сохраняю запись:

function save() { 
    return datacontext.saveChanges(); 
    } 

Вот описание codeFirst этих двух пунктов:

public class Physician 
    { 
    public Physician() 
    { 
     PhysicianSpecialties = new List<PhysicianSpecialty>(); 
     PhysicianPayers = new List<PhysicianPayer>(); 
     IncentivePrograms = new List<PhysicianIncentiveDetail>(); 
     PhysicianNotes = new List<Note>(); 
     PhysInOrgs = new List<PhysInOrg>(); 
     Memberships = new List<Membership>(); 
    } 
    public Int32 Id { get; set; } 
    public Person ContactInfo { get; set; } 
    public ICollection<Membership> Memberships { get; set; } 
    public ICollection<PhysicianIncentiveDetail> IncentivePrograms { get; set; } 
    public ICollection<PhysicianPayer> PhysicianPayers { get; set; } 
    public ICollection<PhysicianSpecialty> PhysicianSpecialties { get; set; } 
    public ICollection<Note> PhysicianNotes { get; set; } 
    public ICollection<PhysInOrg> PhysInOrgs { get; set; } 
    public string Dea { get; set; } 
    public string Npi { get; set; } 
    public string Tin { get; set; } 
    public string Ssn { get; set; } 
    public string TaxId { get; set; } 
    public string MedLicenseNbr { get; set; } 
    public string MedLicenseState { get; set; } 
    public DateTime? MedLicenseRecertDate { get; set; } 
    public EMRSystem EmrSystem { get; set; } 
    public int ImportBatchId { get; set; } 
    public bool IsPcp { get; set; } 
    public bool SoloPractitioner { get; set; } 
    public bool PartOfHospital { get; set; } 
    } 

    public class PhysicianSpecialty 
    { 
    public Int32 Id { get; set; } 
    public Physician Physician { get; set; } 
    public Specialty Specialty { get; set; } 
    public bool IsPrimary { get; set; } 
    } 

Что я получаю, когда я сохраняемого:

Id IsPrimary Physician_Id Specialty_Id 
21 0   NULL   NULL 

Я предполагаю, что при добавлении специальности к врачу графа Breeze автоматически вставляет идентификатор врача и выбранную специальность из раскрывающегося списка, который появляется на странице, когда я нажимаю специальность на currentPhysician() [0].

Может ли кто-нибудь увидеть, что мне не хватает?

Благодаря

+0

Внимательно прочитайте это через электронную почту – Ward

ответ

0

Этот ответ от Ward Bell. Излишне говорить, что это работает, и я спасен!

Проблема была упрощена для одной коллекции в записи врача: Специальности. Я расширил решение для всех других коллекций.

EF Модель

Вашего PhysicianSpecialty.cs класс был определен следующим образом:

public class PhysicianSpecialty 
{ 
    public Int32 Id { get; set; } 
    public Physician Physician { get; set; } 
    public Specialty Specialty { get; set; } 
    public bool IsPrimary { get; set; } 
} 

Вы упускаете внешние ключи (ФКС), которые поддерживают ассоциации, врач и специальность. Breeze требует FK, если вы хотите, чтобы он автоматически поддерживал ассоциации для вас.

Кроме того, без метаданных для описания FKs, Breeze.NET не знал, как установить генерируемые EF столбцы Physician_Id и Specialty_Id.

я пересмотрел его, как это так, с общественными и явными внешними ключами

public class PhysicianSpecialty 
{ 
    public Int32 Id { get; set; } 
    public Int32 PhysicianId { get; set; } 
    public Int32 SpecialtyId { get; set; } 
    public Physician Physician { get; set; } 
    public Specialty Specialty { get; set; } 
    public bool IsPrimary { get; set; } 
} 

Когда EF перестраивает таблицу, теперь он имеет PhysicianId и SpecialtyId столбцов. Я выбираю эти имена, потому что мне они нравятся лучше, чем имена с символами подчеркивания, и они, похоже, соответствуют соглашениям EF (возможно, что и подчеркнутые имена тоже, я не помню).

Теперь эти свойства FK будут установлены, когда вы назначаете ассоциации в клиенте BreezeJS, и все проходит на сервер.

За исключением двух других проблем. выпадающий KO связывания

Следующая оригинальная HTML строка в details.js имеет некорректный KO связывания:

<select data-bind="options: $parent.specialties(), optionsText: 'name', value: specialty()"></select> 

Что вы хотите, это:

<select data-bind="options: $parent.specialties, optionsText: 'name', value: specialty" /> 

Существенная разница в стоимости связывание; вы не можете иметь эти круглые скобки после специальности.

Не могу объяснить, почему. Мой нокаут не достаточно хорош. На самом деле, я действительно удивлен, потому что я не думал, что лишние парнеры пострадали. Видимо, они это делают. Btw, вы абсолютно должны иметь parens для промежуточных значений на пути, как в

data-bind="foreach: phys().physicianSpecialties" 
0

Похоже, что ваши данные экономии частично поэтому не уверены, имеет ли это какое-либо отношение вообще с вашим вопросом, но я столкнулся с проблемой с горячей шаблон Полотенца и ветром. По какой-то причине источник бриза в шаблоне очень сильно отличается даже после обновления через nuget. Попробуйте загрузить из breejejs и заменить источник. Если это не сработает, вы не хуже. Я отправил свой вопрос раньше

Errors when using Breeze with EF

+0

Привет! Я тоже заметил это и обновил Breeze через Nuget, и я до 1.3.3. Тем не менее проблема сохраняется. Я нанял IdeaBlade, чтобы помочь. Я отправлю решение, когда найдем его. – Weej

Смежные вопросы