【问题标题】:Ember.js problems binding content of array controller to content of a different array controllerEmber.js 问题将数组控制器的内容绑定到不同数组控制器的内容
【发布时间】:2013-01-28 09:59:31
【问题描述】:

我们在 Ember.js 中将一个数组控制器的内容与另一个数组控制器的内容相关联时遇到了问题。我们搜索了 Stackoverflow,但似乎没有适合我们的解决方案。

场景很简单。我们有一个名为“Campaign”的模型。该模型非常基本,看起来像这样......

活动模型:

App.Campaign = DS.Model.extend({

    name: DS.attr('string'),
    description: DS.attr('string'),
    opts: DS.attr('string'),
    starred: DS.attr('boolean'),
    keywords: DS.hasMany('App.Keyword')

});

// Create dummy campaign array

App.Campaign.FIXTURES = new Array();

// Populate dummy campaign array

...

Campaign 控制器也是基本的。这是一个简单的 ArrayController,里面什么都没有……

广告系列索引控制器:

App.CampaignsIndexController = Em.ArrayController.extend({

});

为了这个问题,我们已经将我们的应用程序模板剥离到了基本要素。如下所示,应用程序模板有一个侧边栏。侧边栏中有两个视图。一个视图用于网站导航,另一个视图用于“已加星标的广告系列”。此视图将包含整个广告系列的一个子集。

应用模板:

<!-- ================================================== -->
<!-- ======================= APP ====================== -->
<!-- ================================================== -->

<div id="app" class="">

    <!-- ================================================== -->
    <!-- ==================== SIDEBAR ===================== -->
    <!-- ================================================== -->

    <div id="sidebar">

        {{ view App.NavigationView }}

        {{ view App.StarredCampaignsView controller="App.StarredCampaignsController" }}

    </div>

    <!-- ================================================== -->
    <!-- ====================== PAGE ====================== -->
    <!-- ================================================== -->

    <div id="page" class="">

        {{ outlet page }}

    </div>

</div>

我们有一个用于已加星标的广告系列的控制器。这就是事情开始变得混乱的地方。在我们的控制器中,我们将 ArrayController 的内容绑定到 CampaignsIndexController 的内容,其中包含所有 Campaign 模型的数组。

已加星标的广告系列控制器:

App.StarredCampaignsController = Em.ArrayController.extend({

    content: [],

    contentBinding: Ember.Binding.oneWay('App.CampaignsIndexController.content')

});

对于 Starred Campaigns 的视图也很简单...

已加星标的广告系列视图:

App.StarredCampaignsView = Em.View.extend({

    templateName: 'templates/layout/starred-campaigns',

});

这就是已加星标的广告系列模板的外观。它正在尝试遍历 controller.content 中的项目并将它们传递给另一个视图。

已加星标的广告系列模板:

<h5 class="sidebar-title">Starred Campaigns</h5>

<ul class="starred-campaigns clearfix">

    {{# each item in controller.content }}

        {{ view App.StarredCampaignItemView itemBinding="item" }}

    {{/ each }}

</ul>

然而,尽管如此,StarredCampaignsController 中的内容仍然是空的,即使我们填充了由 App.CampaignsIndexController 表示的 App.Campaign 数组。看到我们的方法有什么问题吗?我觉得我们在这里遗漏了一些非常简单的东西。

【问题讨论】:

  • 还有一种更好的方法来插入这样的视图。拿你的NavigationView,你在页面中渲染得很好,但如果它有自己的控制器不是更好吗?如果你使用:{{render "navigation"}},那么 Ember 会自动将App.NavigationView 放在那里,它可以访问App.NavigationController

标签: javascript model-view-controller controller ember.js controllers


【解决方案1】:

在 Ember 中,对于需要其他控制器的控制器,您需要使用 needs 属性。这在 Ember 中总是在变化:在以前的版本中,this.controllerFor 由路由器负责,甚至在更旧的版本中,这种方法更类似于您似乎试图采用的方法。但是,最终方法早已被弃用,控制器/模型/视图的实例不再直接保存在 App 上,只有它们的 object 表示形式。

要直接使用needs,您需要告诉您的App.StarredCampaignsController 控制器它需要App.CampaignsIndexController,如下所示:

App.StarredCampaignsController = Em.ArrayController.extend({
    content: [],
    needs: ['campaigns_index']
});

您现在可以在已加星标的广告系列视图中访问 App.CampaignsIndexController 控制器:{{controllers.campaigns_index}}

查看简单的 JSFiddle:http://jsfiddle.net/AGJfB/

你的不工作的原因是因为你引用了控制器的对象,而不是它的实例:

Ember.Binding.oneWay('App.CampaignsIndexController.content')

虽然您在App 上有一个App.CampaignsIndexController,但这就是它的对象。当您通过任何 Ember 方式(this.controllerForneeds、通过 URL 导航到它等...)访问时,Ember 将为您创建实例。

过去我们可以使用:

Ember.Binding.oneWay('App.campaignsIndexController.content')

但是,这是一种糟糕的处理方式,因为您引用的是控制器的绝对路径。自从 Ember pre 1 以来,我从来没有使用过Ember.Binding.oneWay,但在某些情况下你仍然需要它。但是,当您发现自己在使用它时,最好问问自己是否有必要,以及是否有更好的方法。

我希望我已经很好地解释了自己。请随时提出任何问题!

【讨论】:

  • 感谢{{ render "" }} 的提示。它工作得很好。但是,现在我对从模板中的 App.CampaignsIndexController 访问内容的正确方法感到困惑。
  • 在我的模板中,我有{{ controllers.campaigns_index }},它打印出&lt;App.CampaignsIndexController:ember440&gt;。这很好,因为这意味着它了解控制器实例。但是,在循环内容{{# each item in controllers.campaigns_index.content }} {{ item }} {{/ each }} 时,不会打印任何内容。可能是因为这个模板是在App.CampaignsIndexController 的内容填充数据之前渲染的,所以没有什么可以显示的。这是我对绑定为什么有用的最初想法,因为它会触发和更新。有什么想法吗?
  • 遗憾的是,您遇到了当前的 Ember 错误:github.com/emberjs/ember.js/issues/2025 通过指定下划线,我们得到了控制器,但它是它的不同实例。我们应该使用点表示法 (needs: ['campaigns.index];),但由于错误,我们目前不能。
  • 是否有关于needs 参数的文档?我似乎无法在 Ember.js 的网站上找到它。如果这可行,我将如何引用模板中的内容?
  • 暂时没有,因为它是最近才添加的,但他们总是在更新文档。如果它正常工作,那么它会像这样:{{controllers.index}} 因为如果IndexController 扩展ArrayController 那么它会委托给content
猜你喜欢
  • 2014-05-22
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 2016-11-09
  • 2011-06-06
  • 2019-04-20
  • 2012-02-02
相关资源
最近更新 更多