2017-02-13 40 views
11

我有一个表格,显示人员数据并提供更新人事信息并将更改保存到我的数据库的功能。见以下表格:使用Web API和AngularJS保存表格数据(选择列表)

Figure 1. Personnel Information Form

绑定到我有没有问题,更新文本框的字段。虽然,当涉及到HTML选择列表(下拉列表)时,我无法保存新选择的值。

注:我可以在任意数量的文本框的变化,然后作出选择列表中的更改选择和表格的其余部分保存得当,只是没有更改选择列表,所以它不在任何地方都不会失败。

我没有收到任何错误;然而,我在PUT之前看到了一个额外的OPTIONS请求,这是我不确定的(因此,为什么还要赞赏任何其他提示)。

这里是我的形式:

<form name="personForm" novalidate ng-controller="PersonnelEditCtrl as vm"> 
<fieldset class="col-md-4"> 
    <legend>Basic Personnel Information</legend> 
    <div class="form-group row" ng-class="{'has-error':personForm.inputLastName.$invalid && personForm.inputLastName.$dirty}"> 
     <label class="col-md-3 control-label" for="inputLastName">Last Name</label> 
     <div class="col-md-4"> 
      <input class="form-control" id="inputLastName" name="inputLastName" 
        type="text" placeholder="Last Name (required)" 
        ng-model="vm.person.lastName" required ng-minlength="1" ng-maxlength="30" /> 
     </div> 
     <span class="help-block" has-error"> 
      <span ng-show="personForm.inputLastName.$error.required"> 
       Last name is required. 
      </span> 
      <span ng-show="person.form.inputLastName.$error.minlength"> 
       Last name must be at least 1 character in length. 
      </span> 
      <span ng-show="person.form.inputLastName.$error.maxlength"> 
       Last name cannot exceed 30 characters in length. 
      </span> 
     </span> 
    </div> 
    <div class="form-group row" ng-class="{'has-error':personForm.inputFirstName.$invalid && personForm.inputFirstName.$dirty}"> 
     <label class="col-md-3 control-label" for="inputFirstName">First Name</label> 
     <div class="col-md-4"> 
      <input class="form-control" id="inputFirstName" name="inputFirstName" 
        type="text" placeholder="First Name (required)" 
        ng-model="vm.person.firstName" required ng-minlength="1" ng-maxlength="30" /> 
     </div> 
     <span class="help-block" has-error"> 
      <span ng-show="personForm.inputFirstName.$error.required"> 
       First name is required. 
      </span> 
      <span ng-show="person.form.inputFirstName.$error.minlength"> 
       First name must be at least 1 character in length. 
      </span> 
      <span ng-show="person.form.inputFirstName.$error.maxlength"> 
       First name cannot exceed 30 characters in length. 
      </span> 
     </span> 
    </div> 
    <div class="form-group row" ng-class="{'has-error':personForm.inputMiddleInitial.$invalid && personForm.inputMiddleInitial.$dirty}"> 
     <label class="col-md-3 control-label" for="inputMiddleInitial">Middle Initial</label> 
     <div class="col-md-4"> 
      <input class="form-control" id="inputMiddleInitial" name="inputMiddleInitial" 
        type="text" placeholder="Middle Initial (required)" 
        ng-model="vm.person.middleInitial" required ng-minlength="1" ng-maxlength="1" /> 
     </div> 
     <span class="help-block" has-error"> 
      <span ng-show="personForm.inputMiddleInitial.$error.required"> 
       Middle initial is required. 
      </span> 
      <span ng-show="person.form.inputMiddleInitial.$error.minlength"> 
       Middle initial must be at least 1 character in length. 
      </span> 
      <span ng-show="person.form.inputMiddleInitial.$error.maxlength"> 
       Middle initial cannot exceed 1 characters in length. 
      </span> 
     </span> 
    </div> 
    <div class="form-group row"> 
     <label class="col-md-3 control-label" for="inputDateOfBirth">Date of Birth</label> 
     <div class="col-md-4"> 
      <input class="form-control" ng-model="vm.person.dob" type="date" /> 
     </div> 
    </div> 
    <div class="form-group row"> 
     <label class="col-md-3 control-label" for="selectPayband">Payband</label> 
     <div class="col-md-4"> 

      <select id="selectPayband" name="selectPayband" 
        ng-model="vm.person.payband" ng-options="payband.name for payband in vm.paybands track by payband.id"> 
      </select> 
     </div> 
    </div> 
    <div class="form-group row"> 
     <div class="col-md-4"> 
      <span> 
       <button class="btn btn-primary" style="width:80px; margin-right:10px" 
         ng-click="vm.submit()" ng-disabled="personForm.$invalid">Save</button> 
      </span> 
      <span> 
       <button class="btn btn-default" style="width:70px" 
         ng-click="vm.cancel(personForm)">Cancel</button> 
      </span> 
     </div> 
    </div> 
    <div class="form-group row" ng-show="vm.message"> 
     <div class="col-md-6"> 
      <pre style="font: inherit">{{ vm.message }}</pre> 
     </div> 
    </div> 
</fieldset> 

personnelEditCtrl.js

angular 
.module("personnelService") 
.controller("PersonnelEditCtrl", 
      PersonnelEditCtrl); 

function PersonnelEditCtrl(personnelResource, paybandResource, $filter) { 
var vm = this; 
vm.person = {}; 
vm.message = ''; 
vm.paybands = []; 

paybandResource.query(function (data) { 
    vm.paybands = $filter('orderBy')(data, 'Name'); 
}); 

personnelResource.get({ id: 2 }, 
    function (data) { 
     vm.person = data; 
     vm.person.dob = new Date(vm.person.dob); 
     vm.originalPerson = angular.copy(data); 
    }); 

if (vm.person && vm.person.personId) { 
    vm.title = "Edit: " + vm.person.firstName + " " + vm.person.lastName; 
} 
else { 
    vm.title = "New Person"; 
} 

vm.submit = function() { 
    vm.message = ''; 
    if (vm.person.personId) { 
     vm.person.$update({ id: vm.person.personId }, 
      function (data) { 
       vm.message = '... Save Complete'; 
      }) 
    } 
    else { 
     vm.person.$save(
      function (data) { 
       vm.originalPerson = angular.copy(data); 
       vm.message = '... Save Complete'; 
      }) 
    } 
}; 

vm.cancel = function (editForm) { 
    editForm.$setPristine(); 
    vm.person = angular.copy(vm.originalPerson); 
    vm.message = ""; 
}; 
} 

personnelResource.js

(function() { 
"use strict"; 

angular 
    .module("common.services") 
    .factory("personnelResource", 
      ["$resource", 
      "appSettings", 
       personnelResource]) 

function personnelResource($resource, appSettings) { 
    return $resource(appSettings.serverPath + "/api/people/:id", null, 
     { 
      'update':{method:'PUT'} 
     }); 
} 
}()); 

paybandResource.js

(function() { 
"use strict"; 

angular 
    .module("common.services") 
    .factory("paybandResource", 
      ["$resource", 
      "appSettings", 
       paybandResource]) 

function paybandResource($resource, appSettings) { 
    return $resource(appSettings.serverPath + "/api/paybands/:id"); 
} 
}()); 

数据库结构:

dbo.People

PersonId : int (PK) 
FirstName : string 
MiddleInitial: string 
LastName : string 
DateOfBirth: datetime 
PaybandId : int (FK) 

dbo.Paybands

Id : int (PK) 
Name : string 

,可能还没有关系,但我会发布我的Web API控制器代码“People”以及:

using System.Linq; 
using System.Web.Http; 
using CPS.WebAPI.Models; 
using System.Web.Http.Cors; 
using System.Data.Entity; 

namespace CPS.WebAPI.Controllers 
{ 
[EnableCorsAttribute("http://localhost:53265", "*", "*")] 
public class PeopleController : ApiController 
{ 
    private CPS_Context db = new CPS_Context(); 

    public IQueryable<Person> GetPeople() 
    { 
     return db.Person; 
    } 

    public Person Get(int id) 
    { 
     Person person; 

     if (id > 0) 
     { 
      var people = db.Person; 
      person = people.FirstOrDefault(p => p.PersonId == id); 
     } 
     else 
     { 
      person = db.Person.Create(); 
     } 

     return person; 
    } 

    public void Post([FromBody]Person person) 
    { 
     CPS_Context db = new CPS_Context(); 
     var newPerson = db.Person.Add(person); 
     db.SaveChanges(); 
    } 

    public void Put(int id, [FromBody]Person person) 
    { 
     CPS_Context db = new CPS_Context(); 
     db.Entry(person).State = EntityState.Modified; 
     var updatedPerson = db.SaveChanges(); 
    } 

    public void Delete(int id) 
    { 

    } 
} 
} 

不介意Web API的最低限度代码,我只是从头开始做所有事情,尽可能最小化以使其在同一时间工作。

非常感谢您提供帮助我将选定选项保存在我的选择列表中的任何帮助。如果您有任何其他问题或需要更多信息,请告诉我们 - 我尽可能做到尽可能彻底。再次感谢任何人都可以提供的帮助!

+0

你的选择传递NG-模型试图NG-变化,看看它是否改变了呢? – stackg91

+0

我还没有 - 我仍然得到Angular的颂歌。我现在会研究这个指令。谢谢 – Element808

+0

所以是的,我ng-update工作(只需将选定的值推送到一个数组并显示它)。所以我不确定为什么这不想将新选定的值保存在选择列表中,但是如果它存在于文本框中,它将保存其他所有内容。 – Element808

回答

5

我的问题原来是JSON数据包含导航属性。由于存在参照完整性冲突,更新失败。

我的问题的解决方案是更新我的实体框架数据模型,从JSON中排除导航属性。我加入[JsonIgnore]做这个属性是这样的:

[ForeignKey("Payband")] 
public virtual int PaybandId { get; set; } 

[JsonIgnore] 
public virtual Payband Payband { get; set; }