【问题标题】:Having issues adding components within a ContainerView dynamically在 ContainerView 中动态添加组件时遇到问题
【发布时间】:2014-06-05 19:16:44
【问题描述】:

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

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的好人。

使用:

灰烬: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

【问题讨论】:

    标签: ember.js


    【解决方案1】:

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

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

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

    希望这有帮助!

    更新已修复

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

    好吧,看来您只需要在 foreach 函数之外提供一个参考,并且由于某种原因允许按照记录的方式使用它

    更新 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')
    });    
    

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

    【讨论】:

    • 查看 ember 文档...看来您应该能够直接推入 containerView,因此我不确定为什么它不起作用
    • 你说得对,我无意重复添加相同的组件,但出于我遇到的问题的目的,我没有处理这些。它正在工作,但我得到这个“弃用:不推荐通过其 childViews 属性操作 Ember.ContainerView。请将 ContainerView 实例本身用作 Ember.MutableArray。”。它不会显示在 jsbin 中,但如果您要在本地运行它,它会显示警告消息。
    • 整个 console.log 的内容仍然让我感到困惑,如果我将其注释掉,解决方案将不起作用!我宁愿在我的生产代码中没有 console.log。
    • 是的,这很奇怪,不知道为什么会这样哈哈
    • 我刚刚注意到,如果我们将容器视图放在 {{outlet}} 上方,我们就不需要做那个 self 的事情。又一个怪事!!
    【解决方案2】:

    终于想出了如何摆脱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/

    【讨论】:

    • 嘿这里是另一个选项,除了在子视图中创建一个空白视图,如果某些组件已经存在,它可能很有用。 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') });
    • 整洁,实际上我在集成测试时遇到了问题 出现如下错误:错误:断言失败:在销毁对象上调用 set 但是在添加了你提到的 init 钩子之后,我没有收到任何错误。似乎对于 containerView 我们必须有一个 init 块。我也会更新我的答案。如果您再次发布它作为答案,我会接受它。
    猜你喜欢
    • 1970-01-01
    • 2019-06-29
    • 2015-07-02
    • 2017-04-19
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    相关资源
    最近更新 更多