2017-02-13 76 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; }