0

我无法使用 Knockoutjs 绑定将更新保存到 Breezejs 中的现有数据图。

我从使用 HotTowel 和 Durandal 的 John Papa 的 SPA 开始。

症状是如果更新是医生的简单属性,我可以将更新保存到医生记录。但是,如果我在包含在医生中的一个集合中添加一个新元素,我可以保存集合元素,但它会到达服务器并保存到数据库中,但具有空属性并且没有对医生的引用。我以 Specialty 为例,但我看到在医师记录中添加项目的任何集合都有相同的行为。添加的项目以所有属性中的空值出现在服务器上。

医生图表在页面上显示良好,我可以在适当的情况下将下拉菜单与特定字段的适当值相关联。复选框等也显示适当的值。

这是我正在使用的一段 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

我假设通过向医师图表添加专业,当我将专业推送到 currentPhysician()[0] 时,Breeze 将自动从页面上出现的下拉列表中插入医师 ID 和所选专业。

谁能看到我错过了什么?

谢谢

4

2 回答 2

0

看起来您的数据正在部分保存,因此不确定这是否与您的问题有任何关系,但我遇到了热毛巾模板和微风的问题。由于某种原因,即使在通过 nuget 更新后,模板中的微风源也有很大不同。尝试从 breejejs 下载并替换源。如果它不起作用,你的情况不会更糟。我之前发布了我的问题

将 Breeze 与 EF 一起使用时出错

于 2013-05-15T03:05:00.667 回答
0

这个答案来自沃德贝尔。不用说,它有效,我得救了!

问题被简化为医生记录中的一个集合:专业。我已将解决方案扩展到所有其他集合。

英孚模型

您的 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; }
}

您缺少支持关联、医师和专业的外键 (FK)。当您希望 Breeze 自动为您维护关联时,它需要 FK。

此外,由于没有描述 FK 的元数据,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 的约定(下划线的名称可能也会;我不记得了)。

现在,当您在 BreezeJS 客户端中分配关联时,将设置这些 FK 属性,并且所有内容都流向服务器。

除了你有另外两个问题。组合框 KO 绑定

details.js 中的以下原始 HTML 行具有不正确的 KO 绑定:

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

你想要的是这样的:

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

关键的区别在于值绑定;在专业之后你不能有那些括号。

我无法解释为什么。我的淘汰赛还不够好。在这种情况下,我实际上很惊讶,因为我认为额外的括号不会受伤。显然他们这样做了。顺便说一句,你绝对必须有路径中的中间值的括号,如

  data-bind="foreach: phys().physicianSpecialties"
于 2013-05-23T20:29:14.300 回答