javascript - Backbone js模型保存多次

标签 javascript jquery backbone.js

我正在学习 Backbone js,因此我已经开始创建示例应用程序。

顺便说一句,我现在面临一个问题,即模型在我的数据库中保存了不止一次。我的意思是,当您单击“创建用户”时,您会看到一个表单,因此当我单击“创建用户”按钮时,详细信息会在我的数据库中多次保存,因此所有重复的用户主页中显示的信息。

实际上我正在尝试练习此视频:https://www.youtube.com/watch?v=FZSjvWtUxYk

输出如下所示:http://backbonetutorials.com/videos/beginner/#/new

这是我的代码:

<html>
<head>
<link rel="stylesheet"
    href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/css/bootstrap.min.css">
<script type="text/javascript">
    /*$.getJSON('api/users/1',function(data){

        console.log(data);
    });*/
</script>


</head>

<body>

    <div class="container">
        <h1> User Manager</h1>
        <hr/>       
        <div class="page"></div>
    </div>

    <script type="text/template" id="user-list-template">
        <a href="#/new" class="btn btn-primary">New User</a>
        <hr/>
        <table class="table stripped">
            <thead>
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Age</th>
                </tr>
            </thead>
            <tbody>
                <% _.each(users, function(user){  %>
                <tr>
                    <td><%= user.get('firstName') %></td>
                    <td><%= user.get('lastName') %></td>
                    <td><%= user.get('age') %></td>
                </tr>
                <% }); %>                       
            </tbody>
        </table>
    </script>

    <script type="text/template" id="add-user-template">
        <legend>Create User</legend>
        <form class="add-user-form">
            First Name <input type="text" id="firstName"/><br/>
            Last Name <input type="text" id="lastName"/><br/>
            Age <input type="text" id="age"/><hr/>
            <input type="submit" value="Create User">
        </form>
    </script>


<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>

<script type="text/javascript">

    var UsersList = Backbone.Collection.extend({
        url: 'api/users'
    });

    var User = Backbone.Model.extend({
        urlRoot: 'api/users'
    });

    var UsersListView = Backbone.View.extend({
        el: '.page',
        render: function(){
                var that = this;
                var users = new UsersList();
                users.fetch({
                    success: function(usersList){
                    var template = _.template($('#user-list-template').html())({users: usersList.models});
                    that.$el.html(template);
                }
            });         
        }
    });

    var AddUserView = Backbone.View.extend({
        el: '.page',
        render: function(){
            var template = _.template($('#add-user-template').html())({user:null});
            this.$el.html(template);
        },
        events: {
            'submit .add-user-form': 'saveOrUpdateUser' 
        },
        saveOrUpdateUser: function(e){
            e.preventDefault();
            var userDetails = {firstName: $('#firstName').val(), lastName: $('#lastName').val(), age: $('#age').val()};
            var user = new User();
            user.save(userDetails,{ //SEEMS LIKE HERE HAVING SOME PROBLEM
                success: function(){
                    console.log('INSIDE SUCCESS..');
                    router.navigate('',{trigger: 'true'});
                }
            });             
        }
    });

    var Router = Backbone.Router.extend({
        routes:{
            '':'home',
            'new':'addUser'
        }       
    });

    var router = new Router();
    router.on('route:home',function(){
        var usersListView = new UsersListView();
        usersListView.render();
    });
    router.on('route:addUser',function(){
        var addUserView = new AddUserView();
        addUserView.render();
    });


    Backbone.history.start();

</script>

</body>

</html>

请告诉我出了什么问题以及如何解决这个问题?

最佳答案

@MarciaYudkin,您会注意到,当您首次加载站点并创建用户时,第一个用户不会保存重复项。但是,下次您填写CreateUser时表单,用户将被保存两次。这里发生的事情是你正在遭受僵尸观点的痛苦! (啊!)

“僵尸 View ”是您认为已消失但实际上仍保留在背景中的 View 。既然他们还活着,他们也仍然受其视野的束缚events 。您在代码中检测到的僵尸 View 是:

router.on('route:addUser',function(){
    var addUserView = new AddUserView(); // <---Right here!
    addUserView.render();
});

每次用户关注route:addUser时他们最终创建了一个新的路线 AddUserView 。该 View 会自行渲染并将其自身附加到 DOM。您可能会认为,既然您从 DOM 中“删除”了旧 View ,它就会消失,对吧?好吧,它确实——来自 DOM——但不是来自内存!由于该 View 仍然具有绑定(bind)到 DOM 的事件,因此它不会进行垃圾回收。当绑定(bind)到任何先前 View 的 DOM 元素被触发时(例如通过单击它),当前 View 以及所有旧的、未处理的 View 仍然绑定(bind)到它,并且所有 View 都会响应触发器。这就是发生在你身上的事情。在这里,请参阅这个fiddle我煮好了。

如何修复

解决这个问题的方法是保留对周围 View 的引用,以便您可以正确地处理它。因此,例如,您可以附加对路由器中 View 的引用,然后执行以下操作:

router.on('route:addUser',function(){
   // If the view exists, remove it
   if (router.addUserView) {
     router.addUserView.remove();
     router.addUserView.off();
  }
  router.addUserView = new AddUserView();
  router.addUserView.render();
});

这里我们调用 Backbone.View.remove(),它确实做到了 this.$el.remove()在幕后,有效地删除 View 引用的 DOM 元素并释放绑定(bind)的事件。现在我们的 View 可以被垃圾回收了!

您可以从另一个 Angular 看到我最近如何回答这个问题:Saving User Data more than once 。如果我不包括 Derick Bailey 关于僵尸 View 的开创性文章(我从那里获得大部分信息),我认为我会失职,Zombies! RUN! (Managing Page Transitions In Backbone Apps)

关于javascript - Backbone js模型保存多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28054773/

相关文章:

javascript - 主干模型保存不起作用

javascript - 使用 backbone.js 时键盘 TAB 导航中断

javascript - react : Loop through array of strings

javascript - 使用 JavaScript 遍历 PDF 表单中的所有字段

JavaScript 不遵循下拉列表选择

jquery - 更改 <div> 的背景颜色时.delay() 不起作用

javascript - 单击菜单按钮切换 Logo 图像

javascript - 如何销毁所有 jQuery UI 小部件?

jQuery 更改 FontAwesome CSS 不起作用?

javascript - 正则表达式 - 匹配