【问题标题】:How do I set a property of an Ember Component from another Component?如何从另一个组件设置 Ember 组件的属性?
【发布时间】:2017-04-13 20:24:40
【问题描述】:

所以我创建了这个应用程序的一部分,它有一个模式窗口组件,当你将属性设置为 true 时应该打开它..

application.hbs 有这个:

{{#modal-window enabled=true title="Manage Admins"}}
{{/modal-window}}

在 modal-window.js 中,我有一个 closeModal 操作,它执行 this.set('enabled',false) 并且同样要打开它,您将其设置为 true。

应用底部有一个导航菜单,使用了不同的组件 help-link、admin-link 等。admin-link 也是一个有自己的 hbs 和 js 文件的组件。这就是应用程序的设计方式。在 index.hbs 的底部:

  <div class="configs-list-footer">
{{help-link}}
{{admin-link action='showModal'}}
<div class="logout-link">
  <a {{action 'invalidateSession'}} class="tv-icon">
    <svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><g transform="translate(1.000000, 1.000000)"><path d="M0.347826087,8 L10.7826087,8"></path><polyline id="Stroke-937" points="8 5.2173913 10.7826087 8 8 10.7826087"></polyline><path d="M1.03123478,4.83526957 C2.23471304,2.18831304 4.90253913,0.347617391 8.00027826,0.347617391 C12.2263652,0.347617391 15.6524522,3.77370435 15.6524522,7.9997913 C15.6524522,12.2258783 12.2263652,15.6519652 8.00027826,15.6519652 C4.88862609,15.6519652 2.21036522,13.7952696 1.01453913,11.1288348"></path></g></g></svg>
    <span>Logout</span>
  </a>
</div>

那里的动作调用 admin-link.js 文件中的动作,但似乎没有办法告诉 modal-window 从其自身的外部将启用设置为 true,这是任何程序的基本功能。

在互联网上搜索了几个小时后,我无法弄清楚如何在单击 admin-link 组件(基本上是一个锚标记)时简单地将 modal-window 的“启用”属性设置为 true ..

我已经找到了如何从 Index 路由调用动作,但是就像组件到组件一样,我无法弄清楚如何从 Index 路由更改 modal-window 的属性。

任何时候在线上的任何人询问如何做到这一点,他们都会遇到“组件应该被隔离并且不知道其他所有内容”,而没有明显的方法可以为 UI 做如此基本的事情。

我使用的是 Ember 2.12.1

【问题讨论】:

    标签: ember.js


    【解决方案1】:

    我知道这是一个 Ember 问题;但我强烈建议您查看Quick start documentation of React。关于面向组件的前端开发有很好的解释。 Lifting state up section 中存在的一个特殊短语如下:“通常,多个组件需要反映相同的变化数据。我们建议将共享状态提升到它们最近的共同祖先。”

    你现在就是这种情况。显示模态对话框的状态不属于modal-window 本身,因为您需要从其他地方切换它。因此,您需要在共同祖先处管理此状态;我猜你的情况就是application.js控制器。因此,动作应该冒泡到application 控制器(我的意思是即使模式对话框的关闭也应该由动作中的application 控制器执行)。

    关于您的问题,AFAIK 无法从另一个组件中设置组件的属性。我通常应用的技术是将状态提升到一个共同的祖先。很少,我更喜欢创建service 并在服务中定义属性和函数以维护应用程序范围的状态。因此,如果您更喜欢第二种方法,您可以将服务注入到两个组件中,一个组件可以显示属于该服务的状态,而另一个可以通过服务内的函数对其进行修改。

    您对组件被隔离的看法是正确的。然而,单独工作的组件是无用的;组件应接受所有者的属性,并应提供操作(事件)以进行处理。不要忘记应用数据向下动作向上原则,它通常适用于提升状态向上原则。这是一个很长的描述;但我希望它会有所帮助。

    【讨论】:

    • 我认为您想说的是 mikej 在下面所说的,或者主要是他编写的代码示例。我理解这两个,但都没有解决我的问题,因为我不知道如何使它工作。 application.js,index.js,app.js,xyz.js .. 我不知道该放什么,因为没有人说过,一切都是“把它”放在控制器中“不说该死的地狱”它”是,哪个控制器,哪个文件是明确的,以及将它放在文件中的什么位置。我看到了将其放在 Ember.whatever.extend 之外的示例,将其放在对象中的示例等。
    • 有空的时候,我会尝试在 twiddle 上为您制作一个非常简单的案例演示。
    【解决方案2】:

    这不是您确切问题的答案,但我们用于模态的方法是将组件包装在条件中,而不是使其成为组件的属性。例如

    {{#if manageAdminsIsOpen}}
      {{#modal-window title="Manage Admins"}}
      {{/modal-window}}
    {{/if}}
    

    然后控制器上的操作用于切换manageAdminsIsOpen

    我制作了一个 Ember Twiddle,显示 an example

    【讨论】:

    • 我对模态窗口本身有一个条件,但这是个好主意。然后我可以从路由本身而不是组件来操纵该条件。我仍然希望看到我的问题的答案,只是为了将来的目的。我们的整个应用程序是由外部承包商在 Ember 中构建的,我必须好好学习它。
    • 所以我把这段代码放在那里,但我不确定在哪里定义 manageAdminsIsOpen.. 我假设我从索引路由的操作中用 this.set('manageAdminsIsOpen') 设置它,但我可以'让它工作。
    • 我对此感到非常困惑。我有 application.hbs、application.js、index.js、index.hbs 和大量其他文件,就像在官方 ember 文档中一样,我从来不知道要在哪个文件中放入代码。我只是想把isManageAdmins 在 Ember 扩展部分内的每个 JS 文件中都作为对象的属性,或者只是在该块之外的 javascript 中,无论我把它放在哪里,它都不起作用。是否只是将“manageAdminsIsOpen”放入该 if 块中定义它?是否必须在某处明确定义?
    • 嗨!我为此做了一个示例,并使用链接更新了答案,尽管这可能仍然会让您感到困惑;-) 如果您使用电子邮件地址或 Twitter 更新您的 SO 个人资料,我可以推荐一些您可能会觉得有帮助的教程。
    • 该示例非常有意义,并且在很大程度上是我设置事物的方式,尽管我的模式比这要复杂得多,并且当我将所有东西都放入您的示例中时它说Uncaught TypeError: this.get(...) is not a function at Class.manageClicked (admin-link.js:6) at Backburner.run (ember.debug.js:720) at Backburner.join (ember.debug.js:746) at Function.run.join (ember.debug.js:21556) at ember.debug.js:9478 at Object.flaggedInstrument (ember.debug.js:17747) at HTMLAnchorElement.&lt;anonymous&gt; (ember.debug.js:9477)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 2015-07-28
    • 1970-01-01
    • 2021-02-16
    • 2020-05-17
    • 2020-10-03
    相关资源
    最近更新 更多