我从nouislider保存价值时遇到问题。
这是我的代码:
HTML
<form id="campaignForm" th:object="${campaignForm}" method="post" class="form-horizontal">
<input type="hidden" th:field="*{id}" />
<div class="form-group">
<label class="col-sm-3 control-label">Session lifespan (hours): </label>
<div class="col-sm-7">
<div id="basic_slider" th:field="*{sessionLifespan}">
</div>
</div>
<div class="col-sm-2">
<input class="form-control" id="basic_slider_value" th:value="*{sessionLifespan}"/>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3">
<button class="btn btn-primary" type="submit">Save</button>
<a class="btn btn-white" th:href="@{/campaigns}">Cancel</a>
</div>
</div>
</div>
</div>
</form>
JS
var basic_slider = document.getElementById('basic_slider');
noUiSlider.create(basic_slider, {
start: 0,
step: 1,
behaviour: 'tap',
connect: 'upper',
range: {
'min': 0,
'max': 30
}
});
var basicSliderValue = document.getElementById('basic_slider_value');
basic_slider.noUiSlider.on('update', function( values, handle ) {
basicSliderValue.value = values[handle];
});
basicSliderValue.addEventListener('change', function(){
basic_slider.noUiSlider.set(this.value);
});
控制器
@GetMapping
public String newCampaign(@RequestParam(value = "appId", required = false) Integer appId, Model model) {
CampaignResource campaign = new CampaignResource();
if (appId != null) {
App app = appService.getApp(appId);
AppResource res = appConverter.convert(app);
campaign.setApp(res);
}
return showPage(campaign, model);
}
protected String showPage(CampaignResource campaign, Model model) {
model.addAttribute("campaignForm", campaign);
model.addAttribute("appList", campaignService.getApps());
model.addAttribute("publisherList", campaignService.getPublishers());
model.addAttribute("sourceList", campaignService.getSources());
return "campaigns/campaign-edit";
}
@PostMapping
public String createCampaign(@ModelAttribute("campaignForm") @Validated CampaignResource resource, BindingResult result, Model model) {
if (result.hasErrors()) {
return showPage(resource, model);
}
return saveCampaign(0, resource);
}
@GetMapping("/{campaignId}")
public String editCampaign(@PathVariable int campaignId, Model model) {
Campaign campaign = campaignService.getCampaign(campaignId);
CampaignResource res = campaignConverter.convert(campaign);
return showPage(res, model);
}
@PostMapping("/{campaignId}")
public String updateCampaign(@PathVariable int campaignId, @ModelAttribute("campaignForm") @Validated CampaignResource resource, BindingResult result, Model model) {
if (result.hasErrors()) {
return showPage(resource, model);
}
return saveCampaign(campaignId, resource);
}
protected String saveCampaign(int campaignId, CampaignResource resource) {
Campaign campaign = populateCampaign(campaignId, resource);
int appId = getAppId(resource);
int publisherId = getPublisherId(resource);
int sourceId = getSourceId(resource);
if (campaignId == 0) {
campaignService.createCampaign(campaign, appId, publisherId, sourceId);
} else {
campaignService.updateCampaign(campaign, appId, publisherId, sourceId);
}
return "redirect:/campaigns";
}
protected Campaign populateCampaign(int campaignId, CampaignResource resource) {
Campaign campaign = null;
if (campaignId == 0) {
campaign = new Campaign();
campaign.setTimeAdded(new Date());
} else {
campaign = campaignService.getCampaign(campaignId);
}
campaign.setCampaignName(resource.getCampaignName());
campaign.setDescription(resource.getDescription());
campaign.setStatus(resource.isStatus() ? UserEnums.StatusCampaign.ACTIVE : UserEnums.StatusCampaign.INACTIVE);
campaign.setSessionLifespan(resource.getSessionLifespan());
return campaign;
}
服务
@Transactional
public Campaign createCampaign(Campaign campaign, int appId, int publisherId, int sourceId) {
App app = appRepository.findOne(appId);
campaign.setApp(app);
Publisher publisher = publisherRepository.findOne(publisherId);
campaign.setPublisher(publisher);
Source source = sourceRepository.findOne(sourceId);
campaign.setSource(source);
campaign = campaignRepository.save(campaign);
return campaign;
}
@Transactional
public Campaign updateCampaign(Campaign campaign, int appId, int publisherId, int sourceId) {
campaign.setApp(appRepository.findOne(appId));
campaign.setPublisher(publisherRepository.findOne(publisherId));
campaign.setSource(sourceRepository.findOne(sourceId));
campaign = campaignRepository.save(campaign);
return campaign;
}
转换器
@Override
public CampaignResource convert(Campaign campaign) {
CampaignResource resource = new CampaignResource();
resource.setId(campaign.getId());
resource.setCampaignName(campaign.getCampaignName());
resource.setDescription(campaign.getDescription());
resource.setStatus(campaign.getStatus() == StatusCampaign.ACTIVE);
resource.setSessionLifespan(campaign.getSessionLifespan());
if(campaign.getApp() != null) {
resource.setApp(appConverter.convert(campaign.getApp()));
}
if(campaign.getPublisher() != null) {
resource.setPublisher(publisherConverter.convert(campaign.getPublisher()));
}
if(campaign.getSource() != null) {
resource.setSource(sourceConverter.convert(campaign.getSource()));
}
return resource;
}
错误
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'campaignForm' on field 'sessionLifespan': rejected value [7.00]; codes [typeMismatch.campaignForm.sessionLifespan,typeMismatch.sessionLifespan,typeMismatch.int,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [campaignForm.sessionLifespan,sessionLifespan]; arguments []; default message [sessionLifespan]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'sessionLifespan'; nested exception is java.lang.NumberFormatException: For input string: "7.00"]
当我移动滑块时,它会更改输入字段中的值,但是当我单击“保存”按钮时,没有任何事情发生。如果我从输入标签中删除th:field="*{sessionLifespan}"
,那么它会从表单中保存数据,而对于sessionLifespan,它会保存值0。
答案 0 :(得分:0)
要解决上一个问题,请更改您的javascript代码:
var basic_slider = document.getElementById('basic_slider');
var basicSliderValue = document.getElementById('basic_slider_value');
noUiSlider.create(basic_slider, {
start: basicSliderValue.value,
step: 1,
behaviour: 'tap',
connect: 'upper',
range: {
'min': 0,
'max': 30
}
});
basic_slider.noUiSlider.on('update', function( values, handle ) {
basicSliderValue.value = values[handle];
});
basicSliderValue.addEventListener('change', function(){
basic_slider.noUiSlider.set(this.value);
});
上面的代码将在创建滑块之前从字段中获取值并将初始值设置为它。如果你想让它成为一个int值,你仍然需要使用parseInt
。
您可能已经注意到该问题的原因非常简单,但仍然很难找到,因为您没有注意到在验证模型属性期间出现错误。为了防止出现类似问题,我建议您记录任何BindingResult
相关错误,或使用th:errors
属性在表单中显示它们。两种方式都不能解决问题本身,但它们会提供修复信息。请务必查看this以了解有关th:error
和表单验证的更多信息。