【问题标题】:Backbone Marionette - How to render CompositeView->CollectionView->ItemViewBackbone Marionette - 如何渲染 CompositeView->CollectionView->ItemView
【发布时间】:2017-11-08 22:55:54
【问题描述】:

我正在尝试在我的 Marionette 应用程序中呈现事件部分。我采用了融合包含我的 CollectionView 的复合视图的方法。

我认为 CompositeView 将呈现 CollectionView,然后 CollectionView 将呈现我的 ItemViews(事件)列表。

目前,CompositeView 渲染 CollectionView,但没有 ItemView 被实例化或渲染。

这是我的第一个 Marrionette 应用程序。我正在为 dep 使用节点。管理。 Gulp 构建、浏览器化和 babel。到目前为止,我关注了这个项目以使一切顺利:https://github.com/thejameskyle/marionette-wires

非常感谢您的帮助!!谢谢!

复合视图

import {
  CompositeView
} from 'backbone.marionette';
import {
  CollectionView
} from 'backbone.marionette';
import {
  Collection
} from 'backbone';
import template from './events-template.hbs';
import EventsService from '../services/events-service';
import EventsView from './events-view';
import EventModel from '../models/events-model';
import EventsCollection from '../collections/events-collection';
export default CompositeView.extend({
  template: template,
  className: 'col-md-3 calendar',
  childViewContainer: "ul",
  model:EventModel,



  regions: {
    events: '.events-list',
  },
  initialize: function(){
    let self = this;
    EventsService.find().then(collection => {
      self.collection = collection;
      console.log('Events CompositeView '+self.collection);
      self.childView = new EventsView({collection:self.collection});
    });
  },

  setup(options = {}) {
    this.container = options.container;
    console.log("setup");
  },

  modelsChanged() {
    console.log('Events ModelChanged' + this.model);
  }
});

Events-Template.hbs

<section class="panel">
  <div class="panel-body">
    <div class="monthly-stats pink">
      <div class="clearfix">
        <h4 class="pull-left">Calendar</h4>
        <!-- Nav tabs -->
        <div class="btn-group pull-right stat-tab">
          <a href="#line-chart" class="btn stat-btn active" data-toggle="tab">Week</a>
          <a href="#bar-chart" class="btn stat-btn" data-toggle="tab">Month</a>
        </div>
      </div>
    </div>
    <div class="events-list">

    </div>
  </div>
</section>

CollectionView

import {
  CollectionView
} from 'backbone.marionette';
import {
  Collection
} from 'backbone';
import EventView from './event-view';
export default CollectionView.extend({
  tagName: 'ul',
  childView: EventView,
  childViewContainer: '.events-list',

  getChildView: function(item) {
    console.log('ChildView' +item);
  },

  initialize: function() {
    console.log('EVENTs CollectionView '+this.collection);
    for(let val of this.collection.models) {
      console.log(val.attributes);
    }
  },
  onBeforeRender: function() {
    console.log('Before EVENT CollectionView '+this.collection);
  },
  collectionEvents: {
    all: 'render'
  },
  childEvents: {
    // This callback will be called whenever a child is rendered or emits a `render` event
    render: function() {
      console.log('A child view has been rendered.');
    }
  }
});

ItemView //所有在itemView中的日志只是为了看看有没有被调用。它不是。

import {
  ItemView
} from 'backbone.marionette';
import {
  Collection
} from 'backbone';
import template from './event-template.hbs';


export default ItemView.extend({
  template: template,
  tagName:'div',
  className: 'col-md-3',
  attributes() {

  },
    onShow: function() {
      console.log('Single EVENT');
    },
  initialize: function(o) {
    console.log('init itemView');
  },
  show() {
    console.log("ITEM");
  },
  modelEvents: {
    all: 'render'
  },
  onBeforeRender() {
    console.log("EVENZT VIEW");
  },
  render() {
    console.log("EVENZT VIEW");

  },
  modelsChanged() {
    console.log('Events ModelChanged' + this.model);

  }
});

Event-Template.hbs

 <div class="alert alert-info clearfix">
      <span class="alert-icon"><i class="fa fa-envelope-o"></i></span>
      <div class="notification-info">
        <ul class="clearfix notification-meta">
          <li class="pull-left notification-sender"><span><a href="#">{{eventName}}</a></span></li>
        </ul>
        <p>
          <span>{{program}}</span><span>
        </p>
      </div>
    </div>

【问题讨论】:

  • CompositeViewCollectionView 的扩展 - 你不需要两者。只需将您的收藏连同childViewchildViewOptions 等必要选项一起传递到您的CompositeView
  • 谢谢!!现在,等待渲染 itemview 直到 CollectionView 集合被填充。

标签: javascript backbone.js handlebars.js marionette backbone-views


【解决方案1】:

添加到@J 的评论。 Titus 做了,你问过如何等到CollectionView 的所有ItemView 都渲染完,你可以这样用:

var ItemView = Backbone.Marionette.ItemView.extend({
    onShow: function () {
        this.trigger('childOnShow');
    }
});

var View = Backbone.Marionette.CollectionView.extend({
    childView: ItemView,
    childEvents: {
        'childOnShow': 'onChildShowHandler'
    },
    onChildShowHandler: function () {
        this.count++;
        if (this.count === this.collection.length) {
            // call your function here
        }
    },
    onShow: function () {
        this.count = 0;
    }
});

希望这能解决您的问题。

【讨论】:

    【解决方案2】:

    作为@J。 Titus 已经评论过,您可以使用 CompositeView 或 CollectionView。

    我建议使用CollectionView,因为您只需要一个区域 来显示列表模型视图。

    关于你的集合的事情是你永远不会在你的代码中填充它。当您创建一个新集合时,它是空的,除非您专门传递一个模型数组。所以你需要打电话给.fetch().reset()(我推荐后者用于第一次使用和一次获得很多模型)。

    由于在您的collectionEvents 中,您正在捕获所有事件并进行渲染,因此在加载模型时视图应该会自行更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-02
      • 1970-01-01
      相关资源
      最近更新 更多