当用户想要预览由路线调用的发票时,我正在函数中进行表单验证:
routes: {
"new" : "newInvoice",
"new/:assignmentid" : "newInvoiceAssignment",
"edit/:invoiceid" : "editInvoice",
"preview/:invoiceid" : "previewInvoice",
"preview" : "preview",
"delete/:invoiceid" : "deleteInvoiceModal",
"whyCant" : "whyCant",
"whatsThis" : "whatsThis"
},
这是表格上的两个按钮(实际上是一个按钮和一个href):
<div class="span8 alignRight">
<button id="saveInvoiceDraft" type="submit" class="btn btn-warning">Save Draft</button>
<a id="previewInvoice" class="btn btn-primary">Preview & Send</a>
</div>
创建此发票后,标记的URL设置为:
var url = '#preview';
$('#previewInvoice').attr('href',url);
最后,当我点击“预览和发送”按钮时,下面的previewInvoice(invoiceid)函数运行,正确捕获缺少的一个表单字段并显示错误消息。在那时,即使我填充表单字段,该按钮已经死亡,不再响应。但是,“保存草稿”按钮可以完美地工作,并且模仿与previewInvoice()函数中相同的代码。
我知道可能有更好的方法可以做到这一点,但我是按照这种方式在我继承的应用程序的另一部分完成的。实际上,当我输入这个时,我想知道因为sendDraft()函数工作并且它的按钮和previewInvoice()函数没有,所以它是一个href的事实可能与它有关。
function previewInvoice(invoiceid) {
var invoice = new Invoice({"invoiceid": invoiceid});
invoice.set({"invoiceid": invoiceid,"invoicestatus": "draft"});
formGetter(invoice);
validateInvoiceForm(invoice);
if (window.errors.length == 0) {
//business logic here
if (window.panel == undefined) {
// business logic here
}
else {
//save business logic here
}
}
else {
showInvoiceErrors();
}
}
为什么按钮不再响应的任何想法?我没有在控制台中看到任何错误。我在函数内部添加了一个consol.log来显示不同表单元素的值,它在控制台中第一次显示,但如果我更改数据并再次单击该按钮,则该日志不会更新,这对我来说是另一个线索,它只是没有开火。
答案 0 :(得分:1)
Backbone.History
侦听hashchange
个事件以触发导航到路线。首次单击previewInvoice
按钮时,URL哈希片段将设置为#preview
,并触发匹配的路由。
当你第二次点击同一个按钮时,哈希实际上没有改变,因此路由器没有捕获它。
我很难为这个问题推荐一个好的解决方案。通常我会建议捕获click事件并手动调用router.navigate("preview", {trigger:true});
。但是,根据您的代码示例,您的应用程序看起来像Router
,并且没有View
层用于DOM事件处理,正如您在大多数Backbone应用程序中所期望的那样。
在路由器级别上,解决这个问题有点棘手。在router.navigate
路由执行后,您可以使用preview
设置虚拟哈希。这将导致链接第二次触发hashchange
。不幸的是,这意味着preview
页面不会被收藏,而且由于您没有使用pushState,因此会留下无关的历史记录条目。
我担心这个问题必须通过hacky修复(如上所述)或重大重构来解决。
答案 1 :(得分:1)
我有同样的问题,我的解决方案是放入一个处理程序,它执行从历史中隐藏的虚假“中间”路由,以便Backbone.history将导航注册为更改并触发操作。
将一个类放在需要路由操作触发的链接上,无论URL是否相同:
<a href="/someaction" class="js-ensureNav">do it</a>
在Backbone视图中,输入一个事件处理程序:
events: {
"click .js-ensureNav": "_ensureNav",
},
实际处理程序:
_ensureNav: function (event) {
var route_name = $(event.target).attr('href').slice(1);
Backbone.history.navigate("fake");
Backbone.history.navigate(route_name, {trigger: true, replace: true});
},
答案 2 :(得分:1)
而不是
var url =&#39; #preview&#39;;
$(&#39;#previewInvoice&#39;)ATTR(&#39; HREF&#39;,URL);
试试这个
var date = new Date();
var url =&#39; #preview?date:&#39; +日期;
$(&#39;#previewInvoice&#39;)ATTR(&#39; HREF&#39;,URL);
因此每次生成新请求时都会解决您的问题。