我有些困難。我在AngularJS中使用Rails 4.2.3。我有一個表單需要上傳相關數據模型的嵌套屬性,並且還要上傳圖像。正如我發現,使用AJAX請求上傳文件不是一件容易的事,我使用ng-file-upload來解決這個問題,但是我有一些基本的使用問題。AngularJS - 具有Rails嵌套屬性的ngFileUpload
我的Rails型號:
class Job < ActiveRecord::Base
has_many :references, dependent: :destroy
accepts_nested_attributes_for :references, limit: 5
end
class Reference < ActiveRecord::Base
belongs_to :job
end
Rails的預計提交表單時,格式如下:
Parameters: {"job"=>{"title"=>"Example Title", "company"=>"Example Company", "description"=>"Example Description", "references_attributes"=>{"0"=>{"reference"=>"Example Reference", "id"=>"1"}}, "image"=> #plus the image data here}
隨着NG-文件上傳,看來幾乎是不可能的,包括嵌套屬性(或者也許我我錯過了一些東西,我已經多次閱讀文檔以試圖找到這方面的任何東西)。我採用了這種有點瘋狂的方式,以Rails可以理解的方式包含嵌套屬性。以下表格:
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form ng-submit="save(job)" accept-charset="UTF-8" enctype="multipart/form-data">
<label for="job_title">Title</label>
<input ng-model="job.title"
class="form-control"
id="job_title"
name="job[title]"
type="text"
required />
<div ng-repeat="error in errors.title" class="alert alert-danger">Title {{error}}</div>
<label for="job_company">Company</label>
<input ng-model="job.company"
class="form-control"
id="job_company"
name="job[company]"
type="text"
required />
<div ng-repeat="error in errors.company" class="alert alert-danger">Company {{error}}</div>
<label for="job_years">Years</label>
<input ng-model="job.years"
class="form-control"
id="job_years"
name="job[years]"
type="text" />
<div ng-repeat="error in errors.years" class="alert alert-danger">Years {{error}}</div>
<label for="job_manager">Manager</label>
<input ng-model="job.manager"
class="form-control"
id="job_manager"
name="job[manager]"
type="text" />
<div ng-repeat="error in errors.manager" class="alert alert-danger">Manager {{error}}</div>
<label for="job_contact">Contact</label>
<input ng-model="job.contact"
class="form-control"
id="job_contact"
name="job[contact]"
type="text" />
<div ng-repeat="error in errors.contact" class="alert alert-danger">Contact {{error}}</div>
<label for="job_address">Address</label>
<input ng-model="job.address"
class="form-control"
id="job_address"
name="job[address]"
type="text" />
<div ng-repeat="error in errors.address" class="alert alert-danger">Address {{error}}</div>
<label for="job_description">Description</label>
<textarea ng-model="job.description"
class="form-control"
id="job_description"
name="job[description]"
required>
</textarea>
<div ng-repeat="error in errors.description" class="alert alert-danger">Description {{error}}</div>
<label for="job_skills">Skills</label>
<input ng-model="job.skills"
class="form-control"
id="job_skills"
name="job[skills]"
type="text" />
<div ng-repeat="error in errors.skills" class="alert alert-danger">Skills {{error}}</div>
<label for="job_references">References</label>
<input ng-model="job.references[0]"
class="form-control"
id="job_references_attributes_0_reference"
name="job[references_attributes][0][reference]"
type="text" />
<input ng-model="job.references[1]"
class="form-control"
id="job_references_attributes_1_reference"
name="job[references_attributes][1][reference]"
type="text" />
<input ng-model="job.references[2]"
class="form-control"
id="job_references_attributes_2_reference"
name="job[references_attributes][2][reference]"
type="text" />
<input ng-model="job.references[3]"
class="form-control"
id="job_references_attributes_3_reference"
name="job[references_attributes][3][reference]"
type="text" />
<input ng-model="job.references[4]"
class="form-control"
id="job_references_attributes_4_reference"
name="job[references_attributes][4][reference]"
type="text" />
<label for="job_image">Image</label>
<input ng-model="job.image"
class="width-100"
id="job_image"
name="job[image]"
type="file"
ngf-select
accept="image/*"
ngf-max-size="5MB" />
<div ng-repeat="error in errors.image" class="alert alert-danger">Image {{error}}</div>
<div class="center">
<div class="btn-group">
<input class="btn btn-large btn-primary"
name="commit"
type="submit"
value="Submit" />
</div>
<div class="btn-group">
<a ng-click="back()" href class="btn btn-large btn-default">← Cancel</a>
</div>
</div>
</form>
</div>
</div>
的「哈克」位我指的是我已經有了「job.references [0]」怎麼回事。下面是我如何與它有NG-文件上傳的工作,包括嵌套屬性:
$scope.save = function(job) {
var file = job.image;
Upload.upload({
url: '/api/jobs/' + job.id,
method: 'PUT',
fields: {
'job[title]': job.title,
'job[company]': job.company,
'job[description]': job.description,
'job[years]': job.years,
'job[manager]': job.manager,
'job[contact]': job.contact,
'job[skills]': job.skills,
'job[address]': job.address,
'job[references_attributes][0][reference]': job.references[0],
'job[references_attributes][1][reference]': job.references[1],
'job[references_attributes][2][reference]': job.references[2],
'job[references_attributes][3][reference]': job.references[3],
'job[references_attributes][4][reference]': job.references[4] },
file: file,
fileFormDataName: 'job[image]'
}).progress(function (evt) {
$scope.progress = Math.min(100, parseInt(100.0 * evt.loaded/evt.total));
console.log('Progress: ' + $scope.progress + '% ' + evt.config.file.name);
}).success(function (data, status, headers, config) {
console.log('File ' + config.file.name + 'uploaded. Response: ' + data);
$scope.jobs.push(data);
$state.go('jobs.show', {id: $stateParams.id})
}).error(function (data, status, headers, config) {
console.log('Error status: ' + status);
$scope.errors = data;
});
}
這非常適用於新的模式條目,但是當我在這裏編輯現有條目是哪裏出了問題..這是被髮送到Rails的這種設置JSON數據:
Parameters: {"job"=>{"title"=>"Example Title", "company"=>"Example Company", "description"=>"Example Description", "references_attributes"=>{"0"=>{"reference"=>"Example Reference"}}, "image"=> #plus the image data here}
正如你可能已經注意到了,不再被包含在嵌套的屬性「id」屬性。這導致Rails在我提交任何編輯時複製現有的嵌套屬性。有沒有人有更好的想法,我怎麼可以包含ng-file-upload的嵌套屬性?或者甚至沒有ng-file-upload的解決方案?
在此先感謝!
我沒有看到任何ID屬性上你的頁面不知道究竟是什麼問題。無論如何,你只需將你的json對象作爲'data'而不是'fields'傳遞,它將以json字符串格式發送數據,然後在服務器上將接收到的數據字段的json字符串轉換爲json對象。 – danial
@danial是的,這就是我想弄清楚如何包括。我想過在表單中包含ID輸入字段,或者將它們包含在ng-file-upload的「字段」部分,問題就變成了,他們發送的ID數據沒有任何「引用」屬性的條目, Rails ...我會嘗試你提到的'data'位。 –
@danial是否有可能使用'data'而不將參數發送到服務器,就像'data => {params}'一樣包裝? –