更新backbone.js中的父视图(Updating parent view in backbone.js)

编程入门 行业动态 更新时间:2024-10-27 07:26:43
更新backbone.js中的父视图(Updating parent view in backbone.js)

目标:使用Backbone生成用户表,能够内联编辑这些用户,并在保存时,使用更新的数据重新呈现行。

我正在为具有主UsersView的用户生成容器表。 然后我循环遍历用户集合,并使用UserView为每个用户生成一个表行。 单击任何行上的编辑需要使用编辑表单替换该行。 (与用户关联的字段数多于表中显示的字段数。) 单击“保存”应将编辑表单替换为更新的表格行。

一切都有效,除了重新渲染表格行。 (如果我重新加载页面,更新的用户数据会正确显示,所以我知道它正在保存。)我想要做的(我认为)是获取父视图(UsersView)来监听更改并重新渲染UserView。 经过几十次搜索和不同的尝试,我在这里寻求帮助,告诉我我做错了什么。 提前致谢。

//主要用户视图

var UsersView = Backbone.View.extend( { el: '#content', template: _.template( usersTemplate ), initialize: function( ) { var that = this; this.listenTo( Users, 'change', this.updateOne ); Users.fetch( ); that.render( ); }, render: function( ) { this.$el.html( this.template ); }, // Add a single user to the table addOne: function( user ) { var userView = new UserView( { model: user } ); userView.render( ).el; }, // Add all items in the Users collection addAll: function( ) { Users.each( this.addOne, this ); } });

//个人用户视图

var UserView = Backbone.View.extend({ el: '#usersTableBody', tagName: 'tr', attributes : function( ) { return { 'data-user' : this.model.get( 'display_name' ) }; }, template: _.template( userTemplate ), events: { 'click .editUser': 'editUser' }, initialize: function( ){ }, render: function( ) { var html = this.template( this.model.attributes ); this.$el.html( html ); }, // Switch user row into edit mode editUser: function( e ) { e.preventDefault( ); var userAddEditView = new UserAddEditView( { model: this.model } ); userAddEditView.render( ); } });

//用户编辑视图

var UserAddEditView = Backbone.View.extend({ el: $( '#content' ), template: _.template( userEditTemplate ), events: { 'click .saveUser': 'saveUser' }, initialize: function( options ) { }, render: function( ) { element = '[data-user="' + this.model.get( 'display_name' ) + '"]' this.$el.find( element ).hide( ).after( this.template( this.model.attributes ) ); }, saveUser: function( ) { var display_name = this.$( '#display_name' ).val( ).trim( ); var email_address = this.$( '#email_address' ).val( ).trim( ); var key_email_address = this.$( '#key_email_address' ).val( ).trim( ); var password = this.$( '#password' ).val( ).trim( ); var partner_name = this.$( '#partner_name' ).val( ).trim( ); var hash = this.$( '#hash' ).val( ).trim( ); var salt = this.$( '#salt' ).val( ).trim( ); Users.create( { display_name: display_name, key_email_address: key_email_address, email_address: email_address, password: password, partner_name: partner_name, hash: hash, salt: salt } ); } });

//用户模型

var UserModel = Backbone.Model.extend( { idAttribute: 'key_email_address' });

//用户集合

var UsersCollection = Backbone.Collection.extend( { model: User, url: 'users', initialize : function( models, options ) { }, parse: function( data ) { this.result = data.result; return data.users; } });

The goal: Use Backbone to generate a table of users, be able to edit those users inline, and on save, re-render the row with the updated data.

I'm generating a container table for users with a main UsersView. I'm then looping through a users collection, and using a UserView to generate one table row per user. Clicking edit on any row needs to replace the row with an edit form. (There are more fields associated with a user than are displayed in the table.) Clicking Save should replace the edit form with the updated table row.

Everything works except the re-render of the table row. (If I reload the page, the updated user data is displayed correctly, so I know it's saving.) What I'm trying to do (I think) is get the parent view (UsersView) to listen to the change and re-render the UserView. After dozens of searches and different attempts, I'm here asking for help as to what I'm doing wrong. Thanks in advance.

// Main users view

var UsersView = Backbone.View.extend( { el: '#content', template: _.template( usersTemplate ), initialize: function( ) { var that = this; this.listenTo( Users, 'change', this.updateOne ); Users.fetch( ); that.render( ); }, render: function( ) { this.$el.html( this.template ); }, // Add a single user to the table addOne: function( user ) { var userView = new UserView( { model: user } ); userView.render( ).el; }, // Add all items in the Users collection addAll: function( ) { Users.each( this.addOne, this ); } });

// Individual user view

var UserView = Backbone.View.extend({ el: '#usersTableBody', tagName: 'tr', attributes : function( ) { return { 'data-user' : this.model.get( 'display_name' ) }; }, template: _.template( userTemplate ), events: { 'click .editUser': 'editUser' }, initialize: function( ){ }, render: function( ) { var html = this.template( this.model.attributes ); this.$el.html( html ); }, // Switch user row into edit mode editUser: function( e ) { e.preventDefault( ); var userAddEditView = new UserAddEditView( { model: this.model } ); userAddEditView.render( ); } });

// User edit view

var UserAddEditView = Backbone.View.extend({ el: $( '#content' ), template: _.template( userEditTemplate ), events: { 'click .saveUser': 'saveUser' }, initialize: function( options ) { }, render: function( ) { element = '[data-user="' + this.model.get( 'display_name' ) + '"]' this.$el.find( element ).hide( ).after( this.template( this.model.attributes ) ); }, saveUser: function( ) { var display_name = this.$( '#display_name' ).val( ).trim( ); var email_address = this.$( '#email_address' ).val( ).trim( ); var key_email_address = this.$( '#key_email_address' ).val( ).trim( ); var password = this.$( '#password' ).val( ).trim( ); var partner_name = this.$( '#partner_name' ).val( ).trim( ); var hash = this.$( '#hash' ).val( ).trim( ); var salt = this.$( '#salt' ).val( ).trim( ); Users.create( { display_name: display_name, key_email_address: key_email_address, email_address: email_address, password: password, partner_name: partner_name, hash: hash, salt: salt } ); } });

// User model

var UserModel = Backbone.Model.extend( { idAttribute: 'key_email_address' });

// Users collection

var UsersCollection = Backbone.Collection.extend( { model: User, url: 'users', initialize : function( models, options ) { }, parse: function( data ) { this.result = data.result; return data.users; } });

最满意答案

当集合的项目发生任何更改时,不会触发change事件。

所以你的后续行不应该做任何事情:

this.listenTo( Users, 'change', this.updateOne );

您需要在UserView initialize方法中包含以下内容:

this.listenTo( this.model, 'change', this.render );

因此,无论何时更改模型(编辑时),都会再次呈现当前用户行。

There is no change event fired when any changes occur on the items of a collection.

So your following line shouldn't really do anything:

this.listenTo( Users, 'change', this.updateOne );

you need to include the following in your UserView initialize method:

this.listenTo( this.model, 'change', this.render );

so now whenever the model is changed (on editing), the current user row is rendered again.

更多推荐

本文发布于:2023-08-05 23:56:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1440253.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:视图   js   backbone   view   parent

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!