【问题标题】:Making JointJs & Backbone/Marionette work with collections (HTML items inside)使 JointJs & Backbone/Marionette 与集合一起工作(内部的 HTML 项目)
【发布时间】:2015-12-18 12:21:29
【问题描述】:

如果你能以某种方式帮助我,请告诉我,我有点难以理解。

从一些 Marionette 应用程序逻辑开始:

app.js

//basic setup
this.Graph = new joint.dia.Graph;
this.Paper = new joint.dia.Paper({ width: 640, height: 480, model: this.Graph });

// [...] lots of code

//adding elements
app.Elements.add(element);

到目前为止一切顺利。现在是棘手的部分。我要收藏。

JointCollectionView.js

module.exports = Marionette.CollectionView.extend({
    tagName: 'div',
    className: 'row',
    childView: JointView,

    addChild: function(child, ChildView, index){
        //does that make sense?
        app.Graph.addCell(child);

        //should i add it to collection?
        if (child.shouldBeShown()) {
            return Marionette.CollectionView.prototype.addChild.call(this,   child, ChildView, index);
        }
    },

    getChildView: function(item) {
        return app.Graph.getCell(item);
    }

    //[...]
})

现在更加棘手。如何处理联合视图以使其与集合一起使用并显示 html 元素?

JointView.js

module.exports = joint.dia.ElementView.extend({ /* ?!?!?! */ });

//OR ?

module.exports = Marionette.ItemView.extend({
    jointElementView: null, //this will be like above somewhere else...

    initialize: function(options){
        jointElementView = new JointElementView({ /* ... */ });
    }
})

【问题讨论】:

  • 它是如何为您工作的?
  • 我实际上已经解决了这个问题。 JointElementView 是个坏主意,因为jointjs 不能那样工作。我将更新我的帖子,以便您可以相应地更改您的答案。由于您是唯一一个花时间研究它的人,因此您的观点是当之无愧的。抱歉耽搁了。圣诞节前忙:)
  • 你去。已编辑。修正你的答案,我会批准它:)

标签: backbone.js marionette collectionview jointjs


【解决方案1】:

我不是 JointJS 专家,但您的实现看起来很完美。

您想使用第二个选项:

JointView.js

module.exports = Marionette.ItemView.extend({
  template: _.template("");
  jointElementView: null, //this will be like above somewhere else...

  initialize: function(options){
      this.jointElementView = new JointElementView({ /* ... */ });
  }
});

因为 Marionette.CollectionView 需要 Marionette 视图(例如 Marionette.ItemView 或后代 [LayoutView/CompositeView])。

我要添加到 JointView.js 的方法是将this.jointElementView 的结果注入 JointView.js html。所以,给它添加一个属性,比如:

onRender: function () {
  this.$el.append(this.jointElementView.el); // Where this.jointElementView.el is the JointJS view html
}

【讨论】:

    【解决方案2】:

    在@seebiscuit 的帮助下,我更深入地研究了jointjs,并缩小了我应该如何解决这个问题的范围(不过你似乎对这些问题不感兴趣,所以我会回答自己)

    编辑了以下文件:

    app.js(已更改,很重要!)

    //this step is necessary to create these element before the paper is created.
    //Make jointjs GLOBAL!!!!!!
    joint.shapes.html = {};
    joint.shapes.html.Element = require('views/Element');  //this dude im gonna use to create the elements 
    joint.shapes.html.ElementView = require('views/ElementView');  //this badboy will fire when i create those elements. MAGIC!
    
    //basic setup
    this.Graph = new joint.dia.Graph;
    this.Paper = new joint.dia.Paper({ width: 640, height: 480, model:     this.Graph });
    
    // [...] lots of code
    
    //adding elements
    app.Elements.add(element);
    

    JointCollectionView.js(美/简)

    module.exports = Marionette.CollectionView.extend({
        tagName: 'div',
        className: 'row',
        childView: JointView,
    
        onRender: function(){
          // jointjs' paper is added here long after jointjs custom element init.
          this.el.appendChild(app.Paper.el);
        },
    
        onDestroy: function(){
          // removal of the paper is done here
          this.el.removeChild(app.Paper.el);
        },
    
        buildChildView: function(child, JointView, childViewOptions){
          // add model, jointjs' paper and graph into JointView's options
          var options = _.extend({model: child}, childViewOptions);
              options = _.extend({paper: app.Paper, graph: app.Graph}, options);
    
          return new JointView(options);
        }    
    
        //[...]
    })
    

    JointView.js(魔法在这里!)

    module.exports = Marionette.ItemView.extend({
        tagName: 'div',
        className: 'html-element',
        template: "#agentTmpl",
    
        // store here just in case
        cell: null,
    
        // [...]
    
        initialize: function() {
          // initialize joinjs element-shape here
          Marionette.bindEntityEvents(this, this.model, this.modelEvents);
    
          if(this.cell == null){
            //notice `el: this.el` This will actually pass the option el to ElementView. Surprised? 
            //Yeah me too. From there i can do with the dom-element whatever i want
            this.cell = new joint.shapes.html.Element({ el: this.el, position: { x: 80, y: 80 }, size: { width: 250 } });
          }
        },
    
        onRender: function(){
              // after rendering add cell to graph
              this.options.graph.addCell(this.cell);
        },
    
        onDestroy: function(){
              // after removal remove cell from graph
              this.cell.remove();
        }
    });
    

    Element.js ElementView.js

    为了简单起见,或多或少像这里:http://www.jointjs.com/tutorial/html-elements 总结实际发生的情况是:每当创建新元素时,ElementView 都会触发所有必要的事件(初始化、渲染等)。从那里您可以使用我之前创建的 JointView 的 html 操作绘制的 svg 元素或重叠(类似于教程)。我基本上把我的 JointView dom-element 放在了由 jointjs 绘制的 SVG 上。

    你去。 已修复!

    【讨论】:

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