1

当用户想要预览由路由调用的发票时,我正在函数中进行表单验证:

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 &amp; 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 来显示不同表单元素的值,它第一次显示在控制台中,但是如果我更改数据并再次单击按钮,该日志不会更新,这对我来说是另一个线索,它只是没有开火。

4

3 回答 3

1

Backbone.History侦听hashchange事件以触发导航到路线。当您第一次单击该previewInvoice按钮时,URL 哈希片段设置为#preview,并触发匹配路由。

当您第二次单击同一个按钮时,哈希实际上并没有改变,因此路由器不会捕获它。

我很难为这个问题推荐一个好的解决方案。通常我会建议捕获点击事件并router.navigate("preview", {trigger:true});手动调用。但是,根据您的代码示例,您的应用程序似乎是围绕 构建的Router,并且没有View您在大多数 Backbone 应用程序中所期望的用于 DOM 事件处理的层。

在路由器级别,这有点难以解决。您可以在路由执行router.navigate后使用设置一个虚拟哈希。preview这也会导致链接hashchange在第二次触发。不幸的是,这意味着该preview页面将无法添加书签,并且由于您没有使用 pushState,因此会留下无关的历史记录条目。

恐怕这个问题必须通过 hacky 修复(如上所述)或重大重构来解决。

于 2013-02-05T20:57:41.420 回答
1

代替

var url = '#preview';

$('#previewInvoice').attr('href',url);

尝试这个

var date = new Date();

var url = '#preview?date:' + 日期;

$('#previewInvoice').attr('href',url);

因此,每次都会生成新请求,这将解决您的问题。

于 2014-02-04T12:48:13.267 回答
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});
},
于 2014-01-31T20:52:25.437 回答