【问题标题】:How do I leverage Marionette to rerender a nested CompositeView after a child's model is destroyed?在子模型被销毁后,如何利用 Marionette 重新渲染嵌套的 CompositeView?
【发布时间】:2014-04-21 16:36:53
【问题描述】:

我认为 Marionette 会自动处理删除已损坏模型的视图,但在我的情况下它不起作用。我有一个显示电影集合的 CompositeView。每部电影都有演员名单。当我单击“删除电影”时,它应该删除所有关联的演员并使用已删除的特定电影更新视图。目前,我的应用程序破坏了模型,但视图没有更新。如果我刷新页面,电影和相关的演员都消失了,所以我知道它正在破坏模型,而不是点击它时的视图。我怎样才能让 Marionette 处理这个问题?

相关控制器代码:

 /* in my list_controller.js */

 MovieApp.module("ActorsApp.List", function(List, MovieApp, Backbone, Marionette, $, _){
  List.Controller = {

    listActors: function(){
      var actors = MovieApp.request("actor:entities");
      var movies = new Backbone.Collection;
      var allMovies= MovieApp.request("movie:entities");

      actors.each(function(actor) {
        movieId = actor.get("movieId");

        if (!movies.get(movieId) ){

          //console.log("Movie not found. Adding to list list.");
          movie = allMovies.get(movieId);

          selectedActors = actors.where({ movieId: movieId });

          //console.log("Selected Actors: ", selectedActors);
          movie.actors=selectedActors;

          movies.add(allMovies.get(movieId));

        }
        else {
          console.log("Movie found in list. Skipping.")

        }

      });

      var moviesListView = new List.Movies({
        collection: movies
      });

      moviesListView.on("itemview:actor:new", function(childView, model){
        MovieApp.ActorsApp.New.Controller.newActor(model);
      });

      moviesListView.on("itemview:itemview:actor:show", function(childView, model){
        MovieApp.ActorsApp.Show.Controller.showActor(model);
      });

      moviesListView.on("itemview:movie:show", function(childView, model){
        MovieApp.MoviesApp.Show.Controller.showMovie(model);
      });

      moviesListView.on("itemview:movie:delete", function(childView, model){

        childView.children.each(function(child){
          child.model.destroy();
        });

        // This removes a model from the moviesListView collection
        this.collection.remove(childView.model);  

        this.render();

      });

      moviesListView.on("itemview:itemview:actor:delete", function(childView, model){
        model.model.destroy();
      });

      moviesListView.on("movie:list", function(){
        MovieApp.MoviesApp.List.Controller.listMovies();
      });

      MovieApp.mainRegion.show(moviesListView);

    }


  }
});

这是我的查看代码:

List.Movie = Marionette.CompositeView.extend({
    tagName: "li",
    template: "#actor-movie-list-item",
    itemView: List.Actor,
    initialize: function(){

       console.log("Actors: ", this.model.actors);

        actors = this.model.actors;

        this.collection = actors;

        this.collection = new Backbone.Collection(actors);

    },

    events: {
        "click a.js-remove-movie" : "deleteClicked"
    },

    deleteClicked: function(e){
        e.preventDefault();
        e.stopPropagation();
        this.trigger("movie:delete", this.model);
    },

    appendHtml: function(collectionView, itemView, index){
        var container;

        container = this.$('.recipe-list');
        container.append(itemView.el);
    },


    onRender: function() {
        if(_.isUndefined(this.collection)){
            this.$("ul:first").remove();

        }
        console.log("Movie render called.");
    }

  });

【问题讨论】:

    标签: backbone.js marionette


    【解决方案1】:

    我不完全了解您想要实现的目标,但是如果您想在销毁模型后更新视图,请尝试以下操作:

    recipesListView.on("itemview:movie:delete", function(childView){
        // This removes a model from the recipesListView collection
        this.collection.remove(childView.model);  
    });  
    

    这假定您的 recipesListView 是一个集合或复合视图。 另请查看:http://lostechies.com/derickbailey/2012/04/05/composite-views-tree-structures-tables-and-more/

    我还创建了一个小提琴来演示使用复合视图并通过事件删除项目:http://jsfiddle.net/Cardiff/JEx6Y/

    如果以上内容不能帮助你,你能解释一下吗:
    - 在 list.view 中,this.model.actors 是什么?
    - 您的视图是如何构成的(视图类型的嵌套)
    - 您的数据在模型和集合中是如何定义的?

    【讨论】:

    • 谢谢你,威尔伯特。这绝对是更新视图的方法,但是当我重新加载页面时,已删除的项目会返回。我将您的行添加到我所拥有的内容中,它现在似乎可以工作并且实际上破坏了模型,但我不确定这是否是正确的方法。 childView.children.each(function(child){ child.model.destroy(); });
    • 我已更新原始问题以包含我的控制器代码。我还在学习,所以我想我可能没有正确处理这些关系。 Actor 模型存储一个 movieId 以将它们拉入列表。这可以做得更干净,所以我愿意接受建议。为了回答您关于 this.model.actors 的问题,我正在尝试将关联的演员存储在电影模型中。这似乎不是正确的方法,但现在一切似乎都在工作我只是希望我知道正确的方法。
    • 基本上你想要做的是定义模型之间的关系。看看这个:backbonerelational.org
    • 谢谢,这就是我要找的!我认为 Backbone-relational 将处理我需要的一切。我会将其标记为已接受的答案。
    猜你喜欢
    • 1970-01-01
    • 2017-11-08
    • 2014-10-12
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 2020-09-23
    相关资源
    最近更新 更多