如何从控制台访问已知的Ember组件

16
使用Ember debug Chrome扩展程序,我已经确定了一个我正在尝试自动化的网站中的这个组件(但无法直接访问更改代码):
<MYAPP@component:zipcode-field::ember592>

展示为层次结构:

application
    engine
        myui
            zipcodeField

如果我在调试器中编辑该元素的value属性,它会更新UI和所需的模型。我是否可以通过控制台中的一行代码实现这个功能?

更新:到目前为止,我能够在控制台中输入以下内容:

Ember.lookup.$E.container.lookup("MYAPP@component:zipcode-field")

但在调试器中无法访问/更改其value属性。

更新:

针对其中一个答案的反馈,我的目的是拥有一个控制台一行代码,可以被给予没有任何调试器安装的人以相同的行为运行代码。在控制台中使用变量,例如$ E,需要在运行代码之前手动选择元素,这将不足够。


1
你能链接到相关的网站吗?另外,如果更新value属性有效,那么我认为你可以在Ember之外使用纯JavaScript更新value,然后必要时触发Ember期望的任何事件(如果有的话)? - Jack
1
你评论中的Ember代码有什么意义呢?为什么不直接使用document.querySelector来设置值呢?例如:document.querySelector('input[placeholder="zip code goes here"]').value = '94109'; - Jack
当在控制台中输入来自注释的Ember代码时,似乎能够选择正确的元素,但无法设置/更新Ember模型(抱歉,实际上它可能会更新UI,只是不能更新通常通过手动输入到字段中的模型的其余部分)。它没有唯一的标识符可以通过css/xpath进行定位,只有由Ember生成的id... - ljs.dev
我会尝试在一个页面中复现这个效果/找到另一个公开的示例。在使用Ember、ExtJS等框架时,有些元素可能没有唯一的ID或class来进行css/xpath选择定位,并且由于ID/classes可能会动态生成,每次页面加载时元素数量变化1个,因此每个页面的情况可能不同。 - ljs.dev
1
好的,如果你找到一个公共示例,请告诉我。你可能是对的,没有Ember,你无法以编程方式识别正确的元素,但根据我的经验,总有一些可以作为基础的东西...“哦,它总是在具有这个类的静态文本旁边,或者它总是在广告之后的第四个元素。” - Jack
显示剩余3条评论
3个回答

19

如果我错了,请纠正我,但似乎你没有使用 Ember Inspector(在Firefox书签中都可用)。

一旦安装好它,就可以轻松检查、调试和修改任何与 Ember 相关的内容。为此,本答案将使用 Chrome 版本。

在运行 Ember 应用程序的选项卡中打开 Chrome 开发工具,然后转到开发人员工具中的 Ember 选项卡。

要查看组件,您将需要勾选一个复选框。

enable components

启用后,您将能够看到所有当前使用的组件。

单击组件将打开包含该组件所有属性的面板。

property panel

要从控制台访问这些属性,您只需单击组件旁边的$E

单击后,您应该在控制台中看到类似的东西。

Ember Inspector ($E):  Class {helperName: (...), logout: (...), isOpenBinding: StreamBinding, currentUserBinding: StreamBinding, _morph: Morph…}

现在您需要做的就是获取属性值:

$E.get('myProperty');

设置它们的方法:

$E.set('myProperty', newValue);

非常感谢您提供如此详细的答案。请查看我在原问题中的更新,了解为什么 $E 在这种情况下不会有帮助。 - ljs.dev
第一行说“使用Ember调试Chrome扩展” - 这与Ember Inspector有什么不同吗? - jmurphyau
@leon 如果你使用类似 jQurry 的东西来查找对象并提取它的 ID 属性,那么你就可以使用我回答中的方法。 - jmurphyau
啊,我的错。你可以通过elementId属性为组件设置一个唯一的ID。但是你说你不能修改代码 :/ - Patsy Issa
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Patsy Issa

15

一个组件只是一个视图,所以以下内容应该可以工作:

Ember.View.views[<GUID>]

所以在您的示例中:

Ember.View.views['ember592']

如果您想修改/读取value属性,则需要使用get/set,例如:

Ember.View.views['ember592'].get('value')

Ember.View.views['ember592'].set('value', 'newValue')


是的,您可以使用类似jQuery的工具来查找特定的div(基于类名等),然后提取div的ID属性,这就是GUID“emberXXXX”。 - jmurphyau
你可以循环遍历所有视图。例如,以下代码将循环遍历所有视图并打印toString()的值: - jmurphyau
变量 key 和 view; for (key in Ember.View.views) { view = Ember.View.views[key]; console.log(view.toString()); } - jmurphyau
1
这段代码应该可以正常运行:var key, view; for (key in Ember.View.views) { view = Ember.View.views[key]; if (view.toString().indexOf('<MYAPP@component:zipcode-field::') === 0) { console.log('do stuff'); } } - jmurphyau
此外,Ember 应用程序还有一个容器,您可以使用它来查找对象。其工作方式是:如果对象类型为单例,则返回该单例。如果对象类型不是单例,则创建实例并返回实例。视图不是单例,因此这并没有帮助。控制器是单例的。如果 zipcodeField 值附加到控制器上,您可以像这样访问该控制器:GlobalAppVariable.container.lookup('controller:controller-name')。 - jmurphyau
显示剩余4条评论

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接