【问题标题】:Backbone updating Views主干更新视图
【发布时间】:2014-02-16 20:38:49
【问题描述】:

我正在前端使用 Backbone 制作 Rails 应用程序。我有两个视图,一个用于 Publication 模型,一个用于 Article 模型。在发布视图中有一个“createFeed”函数,当用户填写表单并单击按钮时,该函数会被执行。当发生这种情况时,我希望数据库得到更新,然后重新渲染两个视图。到目前为止没有运气。

这是最初呈现两个视图的主干路由器功能:

home: function(){
    var publications = new SimpleGoogleReader.Collections.Publications();
    publications.fetch({
      success: function(publications){
        var view = new SimpleGoogleReader.Views.PublicationsIndex({model: publications});
        view.render();
      }

    });

    var articles = new SimpleGoogleReader.Collections.Articles();
    articles.fetch({
      success: function(articles){
        var view = new SimpleGoogleReader.Views.ArticlesIndex({model: articles});
        view.render();
      }
    });
  },

这是我在 Backbone 中的发布视图中的 createFeed 函数。帖子请求工作正常,现在只是想弄清楚如何更新视图。

  createFeed: function(e){
    e.preventDefault();
    var feed_url = $('#new_feed_name').val();

    $.post('/publications', {url: feed_url}, function(){
      $.post('/articles/force_update', {feed_url: feed_url}, function(){
          // should I put something here?
      });
    });

  } 

我已经尝试将我在路由器的 home 函数中的代码复制到 createFeed 的回调中,它更新了文章就好了,但是在更新发布视图时引起了问题,我猜是因为那是让视图从其中一个内部呈现自身它的功能。我也尝试将其包含在视图中,但不起作用。

initialize: function() {
  this.listenTo(this.model, "change", this.render);
},

在将正确的数据发送到数据库后,如何让 createFeed 更新两个视图?

感谢任何输入!

* 更新 *

Rida BENHAMMANE 和 Jon McMillan 感谢您的意见。

我现在已经更新了路由器的“home”功能:

 home: function(){
    var publications = new SimpleGoogleReader.Collections.Publications();
    var articles = new SimpleGoogleReader.Collections.Articles();
    var pubIndex = new SimpleGoogleReader.Views.PublicationsIndex({model: publications});
    var artIndex = new SimpleGoogleReader.Views.ArticlesIndex({model: articles});

    // create a method to replace the force_update post in your publications view
    articles.listenTo(publications, "add", articles.force_update);
    publications.fetch();
    articles.fetch();
  },

还有我的 Publication 视图中的 createFeed 函数,如下所示:

  createFeed: function(e){
    e.preventDefault();
    var feed_url = $('#new_feed_name').val();

    this.model.create({
        url: feed_url
    });
  }

这是根据 Jon 的建议。它在制作帖子和呈现发布视图方面效果很好。当然,现在我必须编写代码以发布到文章并根据 Jon 的评论相应地更新它的视图。

这是我应该在“文章”视图中单独执行的操作吗?或者我可以在发布视图的 createFeed 函数中执行此操作吗?如果我分开做,那么我现在会有两个视图都具有相同事件的功能吗?

解决方案! *

出版物索引视图

  initialize: function() {
    this.listenTo(this.model, "sync", this.render);
  },

  render: function(){
    this.$el.html( this.template({publications: this.model.toJSON()}) );
    return this;
  },

  createFeed: function(e){
    e.preventDefault();
    var feed_url = $('#new_feed_name').val();
    var that = this;

    this.model.create(
      {url: feed_url},
      { success: function(data){
          $.post('/articles/force_update', {url: feed_url, publication_id: data.id}, function(data){});
        }
      }
    );

  }

发布路由器

  home: function(){

    var publications = new SimpleGoogleReader.Collections.Publications();
    var articles = new SimpleGoogleReader.Collections.Articles();
    var pubIndex = new SimpleGoogleReader.Views.PublicationsIndex({model: publications});
    var artIndex = new SimpleGoogleReader.Views.ArticlesIndex({model: articles});

    //method to replace the force_update post in your publications view
    articles.listenTo(publications, "sync", function(){
      // var articles = new SimpleGoogleReader.Collections.Articles();
      articles.fetch( {success: function(){}} );
    });

    publications.fetch();

  },

两天后我可以继续我的生活。哈哈。感谢各位大佬的指点!!

【问题讨论】:

    标签: ruby-on-rails backbone.js model-view-controller view frontend


    【解决方案1】:

    您可以使用sync,就像在另一篇已经发布的帖子或许多其他活动中描述的那样。

    请参阅Collection.create()Collection.fetch() 可以listenTo 了解哪些事件。

    initialize: function() {
        this.listenTo(this.model, "sync", this.render);
    },
    createFeed: function(e){
        e.preventDefault();
        var feed_url = $('#new_feed_name').val();
    
        this.model.create({
            url: feed_url
        });
    }
    

    您可以在路由器中监听add 事件来触发第二个帖子。文章视图可以监听force_update 帖子触发的某些事件进行渲染,很像上面的初始化函数。

    home: function() {
        var publications = new SimpleGoogleReader.Collections.Publications();
        var articles = new SimpleGoogleReader.Collections.Articles();
        var pubIndex = new SimpleGoogleReader.Views.PublicationsIndex({model: publications});
        var artIndex = new SimpleGoogleReader.Views.ArticlesIndex({model: articles});
    
        // create a method to replace the force_update post in your publications view
        articles.listenTo(publications, "add", articles.force_update);
        publications.fetch();
        articles.fetch();
    }
    

    通过收听sync,可以移除fetch({success:fn})回调。

    更新

    主要思想是利用 Backbone 的事件系统在集合和视图之间进行对话。如果标准用例适用于您,请使用 Backbone 的默认值,否则请使用 trigger("custom-event")

    SimpleGoogleReader.Collections.Articles的声明里面

            // collection "add" event callbacks pass the model as the first n
            // param to the callback
            force_update: function(publication) {
                var data = {
                    feed_url: publication.get("url")
                };
    
                var callback = _.bind(function() {
                    this.trigger('force-update');
                }, this);
    
                $.post('/articles/force_update', data).done(callback);
            }
        });
    

    SimpleGoogleReader.Views.ArticlesIndex里面

            initialize: function() {
                this.listenTo(this.model, "force-update", this.render);
            }
    

    【讨论】:

    • 这成功了!我需要花时间熟悉渲染方法。
    • 在发布到文章之前是否需要完成新出版物的创建(来自服务器的响应)?
    • 是的,我愿意。我在这里提出了一个新问题:stackoverflow.com/questions/21821134/…
    【解决方案2】:

    最好的方法是:

    1- 使用主干集合的sync 函数将其状态持久化到服务器而不是使用$.post()

    2- 将sync 事件绑定到视图渲染:

    initialize: function() {
      this.listenTo(this.model, "sync", this.render);
    }
    

    3- 在某处保留对您的集合的引用,因此每当您想使用客户端状态更新服务器时,调用集合sync 方法,如果成功完成,您的视图将被重新呈现。

    【讨论】:

    • 对不起,这有点混乱,我如何使用同步? Backbone 新手。
    • 你可以这样使用publications.sync('update');backbonejs.org/#Collection-sync
    猜你喜欢
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-18
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多