在backbone.js中处理重新渲染视图的最佳方法是什么?

4

我有以下视图:

Main.Views.Login = EventQ.View.extend({
events: {
    "submit form": "login"
},

template: "login",

login: function(e) {
    var me = this;

    $.ajax({
        url: "/api/users/login",
        type: 'POST',
        dataType: "json",
        data: $(e.currentTarget).serializeArray(),

        success: function(data, status){
            EventQ.app.router.navigate('dashboard', true);
        },

        error: function(xhr, status, e) {
            var result = $.parseJSON(xhr.responseText);
            me.render_with_errors(result.errors);
        }
    });

    return false;
},

render: function(done) {
    var me = this;

    // Fetch the template, render it to the View element and call done.
    EventQ.fetchTemplate(me.template, function(tmpl) {
        me.el.innerHTML = tmpl(me.model.toJSON());
        done(me.el);
    });
},

render_with_errors: function(errors) {
    var me = this;

    // Fetch the template, render it to the View element and call done.
    EventQ.fetchTemplate(this.template, function(tmpl) {
            me.el.innerHTML = tmpl(errors);
    });
}
});

以及像这样的简单模板:

<form>
<input name="username" />
<input name="password" />
<button type="submit" />
</form>

我希望您能在错误返回时重新渲染模板但保留输入内容。错误模板应如下所示:

<form>
<input name="username" />
<label class="error">required</label>
<input name="password" />
<button type="submit" />
</form>

有没有一种方式可以将视图与模型绑定或者其他我可以检查的东西?现在,render_with_errors可以工作,但是问题在于我失去了填写表单的所有数据。


1
你有没有考虑不使用单独的错误模板?也许在你的实际情况中,模板更加不同。但在你的例子中,你可以在错误/成功处理程序中显示/隐藏错误消息。甚至可以进行一些即时验证。 - Paul Hoenecke
2个回答

1

人们常常陷入这样的思维模式,认为只有重新呈现模板才能改变页面。但呈现模板只是更新页面的一种解决方案。您仍然可以从backbone视图内部自由使用传统方法。因此,另一个可能的解决方案是从视图中简单地调整dom。

因此,请将您的模板设置为以下内容:

<form>
<input name="username" />
<label class="error" style="display:none">required</label>
<input name="password" />
<button type="submit" />
</form>

然后在您的登录函数中进行以下更改:

error: function(xhr, status, e) {
    var result = $.parseJSON(xhr.responseText);
    me.showLoginError();
}
showLoginError: function() {
    this.$('.error').show();
}

当然,你总是可以添加更多内容,例如消息自定义等。

重要的是要记住,完整模板呈现不是你的backbone代码对应用程序状态更改做出反应的唯一方式,通过其他方法操作DOM也是可以的。


0
假设你有这样一个模型:
Main.Models.LoginModel = EventQ.Model.extend({
    /* ... */
    defaults: {
        'username': "",
        'password': ""
    },
    /* ... */

当您的Ajax请求成功时,您可以导航到下一页。 如果失败,您可以将模型设置为使用未定义来指示缺失值:

// assumed you did not enter your password
this.me.model.set( { 'username': textBoxValueSoFar, 'password': undefined });

然后可以建立一个类似这样的模板(它将与第一页加载时相同):

<form>
    <input name="username" value="{{username}}" />
    {{#unless username}}
    <label class="error">required</label>
    {{/unless}}
    <input name="password" value="{{password}}" />
    {{#unless password}}
    <label class="error">required</label>
    {{/unless}}
</form>

{{unless}} 检查值是否不为 false、undefined、null 或 []。因此,在第一次页面加载时,它是一个空字符串,不提供错误消息。

有关“unless”的更多详细信息,请参见http://handlebarsjs.com/

所以你要做的是:使用空字符串表示到目前为止没有输入错误的值。您可以使用 undefined 来检查是否已输入错误的值(实际上是什么都没有输入)。 在您的模板中,您可以检查这个并采取适当的行动。


1
当模型发生变化时,如何使模板自动更新?否则,您将被困在重新渲染模板的困境中。 - nimrodm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接