【问题标题】:How do I programmatically add child views to an Ember view at specific DOM selectors?如何以编程方式将子视图添加到特定 DOM 选择器的 Ember 视图?
【发布时间】:2013-08-15 19:10:32
【问题描述】:

我有一个视图,它使用 3rd 方库在 didInsertElement 挂钩中呈现额外的 DOM 元素。添加这些新元素后,我需要在其中添加一些子视图,以便它们可以渲染动态数据。

这是我尝试过的:

App.MyView = Ember.View.extend({
  didInsertElement: function() {
    create3rdPartyDomElements();
    var element = this.$('someSelector');
    childView = this.createChildView(App.SomeViewClass, attributesDict);
    childView.appendTo(element);
  }
});

(jsbin:http://jsbin.com/idoyic/3)

这会按预期呈现我的视图,但在 Ember RC 7 中会出现以下断言错误:“您不能附加到现有的 Ember.View。请考虑改用 Ember.ContainerView。”

按照here 的建议,我已尝试扩展 ContainerView,这可行,但我无法在特定的 DOM 选择器处插入子视图。它只是在父视图的开头插入子视图。

有人可以帮帮我吗?非常感谢!

【问题讨论】:

  • 你想在生成的 dom 中使用绑定或其他一些 ember 技术吗?还是只是视觉上的东西,并不重要?你的第三方库是什么?
  • 它是 codemirror.net 是的 - 我需要在生成的 dom 中使用绑定。不是在编辑器中同步代码,而是在编辑器中添加额外的可视化小部件。
  • 这个 hack 是在 IRC 上提出的,但在切换了几条路线后似乎会产生一些丑陋的副作用:jsbin.com/owepeh/1
  • 不错的@AndreiSoare,但是,我们添加了 run.next 代码?没有它也能正常工作
  • 是的,它似乎可以在没有 run.next 的情况下工作。但是正如我所说,它引入了一些副作用:离开路线并再次进入时,开始出现其他问题:-s

标签: ember.js


【解决方案1】:

这就是我的创作方式:

一个实现,其中您有主视图,在这种情况下,codemirror,在中间。并且可以在顶部或底部添加更多视图。

App.EditorView = Ember.View.extend({
  templateName: 'editor-view',
  topView: Ember.ContainerView.extend(),
  bottomView: Ember.ContainerView.extend(),
  CodeMirrorView: Ember.TextArea.extend({  
    didInsertElement: function() {      
      this.codeMirror = CodeMirror.fromTextArea(this.get('element'));                  
    }
  })
});

模板:

<script type="text/x-handlebars" data-template-name="editor-view">
  {{view view.topView viewName="topViewInstance"}}
  {{view view.CodeMirrorView}}
  {{view view.bottomView viewName="bottomViewInstance"}}
</script>

表示自定义组件的视图:

App.MyComponent = Ember.View.extend({
  templateName: 'click-here',
  message: null,
  click: function() {
    alert(this.get('message'));
  }
});

实现:

App.MyEditorView = App.EditorView.extend({  
  didInsertElement: function() {
    this._super();
    this.get('topViewInstance').pushObject(App.MyComponent.create({ message: "Hello" }));

    this.get('bottomViewInstance').pushObject(App.MyComponent.create({ message: "World" }));
  }
});

这样可以创建一个新实例,或扩展App.EditorView 并在顶部或底部插入更多视图。因为 topViewbottomViewEmber.ContainerViews,所以添加的所有视图都将具有绑定、事件和其他 ember 功能。

查看该 jsbin 以查看它是否正常工作 http://jsbin.com/ucanam/686/edit

【讨论】:

  • 嗨,Marcio - 感谢您的彻底回答。这不完全是我的想法,因为我希望能够将视图添加到由 CodeMirror.fromTextArea() 生成的 DOM。这就是我在代码中使用 this.$('someSelector') 的原因。如果你看这里codemirror.net/demo/widget.html,你会看到在编辑器中添加了一些小部件,在两行之间。我想添加类似的小部件,由 Ember 视图呈现。
  • 嗯,现在我明白了。没问题,有时间我会检查的。因为我没有在 codemirror 中创建小部件。乍一看不知道怎么回答。
  • 不用担心。我避免提及 codemirror 是因为我正在寻找一个通用的解决方案来解决这个问题:如何以编程方式将子视图添加到特定 html 元素的视图中,而不仅仅是在父视图的开头/结尾?
【解决方案2】:

您可以将子视图渲染到父视图的隐藏 div 中,然后将它们分离并附加到 didInsertElement 钩子中的任意 DOM 元素。

http://jsbin.com/qaqome/1/

有关相关问题(组件而不是视图),另请参阅 this question

【讨论】:

    【解决方案3】:

    尝试在您的视图中添加一个属性,如下所示:

    App.MyView = Ember.View.extend({
      childViewsContainer: Em.ContainerView.create({}),
      didInsertElement: function() {
        create3rdPartyDomElements();
        var element = this.$('someSelector');
        childViewsContainer.createChildView(App.SomeViewClass, attributesDict);
        childView.appendTo(element);
      }
    });
    

    然后,您可以访问您的 childViewsContainer 并使用它做任何您想做的事情

    【讨论】:

    • 这不起作用,它给出了同样的错误和另一个弃用警告:不再支持使用 defaultContainer。 [defaultContainer#lookup] 见:git.io/EKPpnA
    • 我创建了 2 个 jsbin,一个是我最初的尝试,一个是你的建议。随意玩:jsbin.com/idoyic/3jsbin.com/irifes/2
    猜你喜欢
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    相关资源
    最近更新 更多