useShadowDom = false时查询组件的子元素

时间:2015-01-16 16:50:15

标签: dart angular-dart

我正在将useShadowDom: false与我的组件一起使用,以尝试支持更多浏览器,而无需使用麻烦的web_components polyfill。启用shadow DOM后,我会做这样的事情:

void onShadowRoot(ShadowRoot root) {
  root.querySelector('.btn-go-back').onClick.listen((e) {
    if (goBackHandler != null) {
      goBackHandler();
    }
  });
}
在加载我的组件模板后,

onShadowRoot将运行,因此DOM中存在所有组件元素。如果没有启用Shadow DOM,我会在构造函数中注入组件的根元素,并执行以下操作:

MyComponent(this._root){
  _root.querySelector('.btn-go-back').onClick.listen((e) {
    if (goBackHandler != null) {
      goBackHandler();
    }
  });
}

这不起作用,因为组件的模板尚未加载到DOM中,因此根元素没有任何子查询。

我已尝试实现AttachAware,并在attach()方法中查询根元素,并且此时也未加载模板。

所以,如果我没有使用shadow DOM,我如何知道模板何时加载到DOM中,以便查询组件中的元素?

修改

如果您尝试查询提供的ShadowRootAware对象,则尝试将onShadowRootuseShadowRoot: falseShadowRoot一起使用会导致以下错误:

Unsupported operation: Not supported

STACKTRACE:
#0      EmulatedShadowRoot._notSupported     (package:angular/core_dom/emulated_shadow_root.dart:5:21) 
#1      EmulatedShadowRoot.querySelector (package:angular/core_dom/emulated_shadow_root.dart:32:63)

我还尝试了以下组合:

  • 在构造函数中注入根元素和
  • 查询onShadowRoot中的根元素哪个有效,但是现在我在控制台输出中看到了这个:

[WebPlatformShim] WARNING: Failed to set up Shadow DOM shim for [find-result].

InvalidCharacterError: The string contains invalid characters. '[find-result]' is not a valid attribute name.

因此,出于某种原因,即使我的所有组件都将useShadowDom设置为false,它仍然在尝试使用ShadowDom垫片。我假设这是因为我实施ShadowRootAware构建EmulatedShadowRoot。所以,我认为我需要一个避免onShadowRoot

的解决方案

3 个答案:

答案 0 :(得分:5)

您可以按如下方式查询模拟组件的模板:

class Component implements ShadowRootAware {
  Element el;

  Component(this.el);

  void onShadowRoot(_) {
    this.el.querySelector('.blah');
  }
}

错误消息:

[WebPlatformShim] WARNING: Failed to set up Shadow DOM shim for [find-result].

是由css shim引起的。这是垫片的限制之一(您只能使用元素选择器)。

您可以禁用css shim。然后你不会看到错误,但你不会有CSS封装。

在此处查看更多信息:

https://github.com/angular/angular.dart/wiki/CSS-Shim

答案 1 :(得分:2)

我们安排子元素查询下一个事件循环迭代。我不了解特定的内部实现细节,但它对我们来说可以正常工作:

MyComponent(Element root) {
  // Schedule child elements querying on the next event loop iteration when
  // AngularDart will render the child DOM.
  new Future(() {
    root.querySelector('.btn-go-back').onClick.listen((e) {
      if (goBackHandler != null) {
        goBackHandler();
      }
    });
  });
}

答案 2 :(得分:1)

即使onShadowRoot,您也可以使用useShadowDom: false。但是,提供的参数不是ShadowRoot对象。