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

发布于 2025-01-03 06:57:50 字数 1623 浏览 0 评论 0原文

我有以下视图:

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 可以正常工作,只是我丢失了表单上填写的所有数据。

I have the following view:

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);
    });
}
});

and a simple template like this:

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

what I'm looking to do is be able to re-render the template if errors are returned but keep the input's populated. An error template would like like:

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

Is there a way to bind the view to a model or something that I can check? Right now the render_with_errors works except for the fact that I lose all the data filled out on the form.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼前雾蒙蒙 2025-01-10 06:57:51

人们通常会陷入这样一种模式,他们认为改变页面的唯一方法就是完全重新渲染模板。但渲染模板只是更新页面的一种解决方案。您仍然可以在主干视图中自由使用传统方法。因此,另一种可能的解决方案是您只需从您的角度调整 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();
}

当然,您始终可以添加更多内容,消息自定义等。

重要的是要记住,完整的模板渲染并不是唯一的方法为了让你的主干代码能够对应用程序状态的变化做出反应,并且可以使用渲染以外的方法来操作 DOM。

It's common for people to get in the mode where they only way they think that the only way they can change the page is a full re-render of a template. But rendering templates are only 1 solution to updating the page. You are still free to use traditional methods from within your backbone view. So another possible solution is for you to simply adjust the dom from your view.

So make your template be the following:

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

And then make the following change in your login function:

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

And of course you can always add more to that, message customizations, etc.

It's just important to remember that full template renders aren't the only way for your backbone code to react to changes in the application state, and it's ok to manipulate the DOM in a method other than render.

冷…雨湿花 2025-01-10 06:57:51

假设您有一个这样的模型:

Main.Models.LoginModel = EventQ.Model.extend({
    /* ... */
    defaults: {
        'username': "",
        'password': ""
    },
    /* ... */

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

// 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、未定义、null 或 []。因此,在第一页加载时,它是一个空字符串,并且不提供错误消息。

有关更多详细信息,请参阅 http://handlebarsjs.com/ 带有“除非”的部分。

所以你要做的是:使用一个空字符串来指示到目前为止没有输入错误的值。您可以使用 undefined 来检查是否输入了错误的值(实际上什么也没有)。
在您的模板中,您可以适当地检查此行为。

Supposed you have a Model like this:

Main.Models.LoginModel = EventQ.Model.extend({
    /* ... */
    defaults: {
        'username': "",
        'password': ""
    },
    /* ... */

When your Ajax-Request successes, you can navigate to the next page.
If it fails, you can set your model to use undefined to indicate a missing value:

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

Then can built up an template like this (it will be the same as on first page load):

<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}} checks if, the value is not false, undefined, null or []. So on first page load, it is an empty string and no error message is provided.

See http://handlebarsjs.com/ the part with "unless" for more details.

So what you do is: you use an empty string to indicate that no wrong value has been entered so far. You use undefined to check if a wrong value (in fact, nothing) has been entered.
In your template you can check for this an act appropriately.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文