在ContainerView中动态添加组件时遇到问题

时间:2014-06-05 19:16:45

标签: ember.js

我在应用程序级别有一个容器视图,我想通过一些操作向这个容器视图中添加一些组件。我这样做的方式是:

1)我将一些对象推送到应用程序控制器

2)ContainerView在应用程序控制器的上下文中,所以我观察了持有步骤1中提到的对象的数组的长度

3)然后我创建组件并将它们附加到容器视图

我注意到一个奇怪的事情是最初在容器视图中定义的观察者没有触发,但是我在登录控制器时添加了初始化钩子,然后观察者开始为我工作。这告诉我也许我做的不对。这是我的容器视图:

App.MyContainerView = Ember.ContainerView.extend({
    initialize: function(){
        //IF YOU WERE TO COMMENT THIS CONSOLE.LOG THEN THE OBSERVER NEVER GETS HIT WHEN YOU CLICK ON ADD BUTTON. MAYBE CONTROLLER IS NOT SET UP AND IT NEEDS SOME TIME???
        console.log(this.get('controller').toString());
    }.on('init'),

    appendMyComponent: function(){
        console.log("inside the observer");
        this.get('controller.myComponents').forEach(function(comp){
        console.log(this.toString());
        this.pushOject(App.MyTestComponent.create({}));
        }, this);
    }.observes('controller.myComponents.length')
});  

我是否必须使用命名插座,然后在插座内渲染容器视图?不知道我在这里做错了什么。

这是一个jsbin:http://emberjs.jsbin.com/xamoxese/2/

非常感谢您的反馈。非常感谢stackoverflow。

使用:

Ember:1.5.0 把手:1.3.0 jQuery:1.10.2

还有一些更新,最初由@bmeyers提供的解决方案虽然在jsbin中工作但并不适合我。所以在我的真实应用程序mu中,application.hbs看起来像这样:

{{outlet navbar}}
{{outlet}}
{{outlet modal}}
{{view App.MyContainerView}}

然后我重新订购它:

{{view App.MyContainerView}} 
{{outlet navbar}}
{{outlet}}
{{outlet modal}}

然后解决方案有效。现在只有我能摆脱那个console.log的东西:) 这是我在@bmeyers解决方案http://emberjs.jsbin.com/xamoxese/10/

之上添加的更新的jsbin

2 个答案:

答案 0 :(得分:1)

我已经为您解决了这个问题,并在此处显示了一个示例:http://emberjs.jsbin.com/xamoxese/3/edit?html,css,js,output

我没有解决你的问题,你一遍又一遍地添加相同的组件,从不清除childView数组,但也许这是你的意图。

基本上你没有推送到容器视图,你需要推送到childViews属性。

希望这有帮助!

UPDATE FIXED

http://emberjs.jsbin.com/xamoxese/6/edit

好的,所以看起来你只需要在foreach函数之外引用一个引用,并且由于某种原因允许以它的文档记录方式使用它

UPDATE 2 ::将containerView代码更改为....

App.MyContainerView = Ember.ContainerView.extend({
  init: function() {
    this._super();
    this.appendMyComponent();
  },

  appendMyComponent: function(){
      this.get('controller.myComponents').forEach(function(comp){
        this.pushObject(App.MyTestComponent.create({}));
    }, this);
  }.observes('controller.myComponents.length')
});    

这比创建一个永远不会使用的空视图感觉更清晰。我知道挑剔,但这让我烦恼。

答案 1 :(得分:0)

最后想出了如何摆脱那个console.log的事情。所以我实际上有两个解决方案:

1)将控制器传递给容器视图

{{view 'myContainer' controller=this}}

2)将空视图设置为ContainerView

App.MyContainerView = Ember.ContainerView.extend({
    childViews: [Ember.View.create()],

    appendMyComponent: function(){
        this.get('controller.myComponents').forEach(function(comp){
        this.pushOject(App.MyTestComponent.create({}));
        }, this);
    }.observes('controller.myComponents.length')
});  

实际上最好的解决方案就像@bmeyers所建议的那样,就是拥有容器视图的init函数:

init: function() {     
    this._super();     
    /*
     THIS IS THE OBSERVER METHOD THAT WE HAVE IN THE VIEW, THIS CALL DOES NOT EVEN
     NEED TO ADD A CHILD VIEW, BUT STILL NEEDS TO BE CALLED - STRANGE I KNOW BUT WHY
     I AM NOT SURE. ALSO FACED ISSUE DURING TEST FOR ABOVE 2 APPROACHES, THIS ONE WORKED WELL
     */
    this.appendMyComponent();
}

这是工作的jsbin:http://jsbin.com/xamoxese/13/