自定义属性会将自定义元素样式重新注入头部

时间:2017-07-14 22:45:43

标签: aurelia shadow-dom

在我的aurelia应用程序中,我的一个自定义元素panel(shadow DOM)包含另一个自定义元素widget(shadow DOM),它具有自定义属性own-attribute(模板控制器)它。 panel有一个范围样式表(<require from="./panel.css" as="scoped"></require>)。在编译时,aurelia正确地将./panel.css注入panel的阴影根。但是,在单独的步骤中,在own-contextwidget上编译panel时,aurelia会将./panel.css注入<head>,从而打破了自定义元素样式表的抽象,通常会对我的应用程序造成严重破坏。

我该如何解决这个问题?

我尝试制作一个羽毛here,但它不起作用。我正在使用ES2017,这会让生活更加复杂。

这是一个问题。 HtmlBehaviorResource.compile()ViewResource.compile()的调用未传递编译指令,因此后者使用默认值。因此,CSS钩子不会得到它们应该注入阴影根的消息。更不用说这是没有充分理由双重注射这些样式。

at eval (eval at injectStyles (http://example.com/jspm/npm/aurelia-pal-browser@1.1.0/aurelia-pal-browser.js), <anonymous>:1:11)
at Object.injectStyles (http://example.com/jspm/npm/aurelia-pal-browser@1.1.0/aurelia-pal-browser.js:434:27)
at ViewCSS.beforeCompile (http://example.com/jspm/npm/aurelia-templating-resources@1.2.0/css-resource.js:105:25)
at ViewResources._invokeHook (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:1281:25)
at ViewCompiler.compile (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2509:17)
at HtmlBehaviorResource.compile (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:3972:46)
at ViewCompiler._compileElement (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2813:40)
at ViewCompiler._compileNode (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2543:23)
at ViewCompiler._compileNode (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2565:33)
at ViewCompiler.compile (http://example.com/jspm/npm/aurelia-templating@1.2.0/aurelia-templating.js:2512:12)

panel.js

import { useShadowDOM, customElement } from 'aurelia-templating';

export { PanelModule };

@useShadowDOM
@customElement('panel-elem')
class PanelModule {}

panel.html

<template>
    <require from="./panel.css" as="scoped"></require>

    <require from="lib:widget"></require>
    <require from="lib:own-context"></require>

    <widget-elem own-context>
        <content>
            some content
        </content>
    </widget-elem>
</template>

widget.js

import { useShadowDOM, customElement } from 'aurelia-templating';

export { WidgetModule };

@useShadowDOM
@customElement('widget-elem')
class WidgetModule {}

widget.html

<template>
    <require from="./widget.css" as="scoped"></require>

    <div id="thing">
        <slot></slot>
    </div
</template>

自有context.js

import { inject, templateController, BoundViewFactory, ViewSlot } from 'aurelia-framework';
import { createOverrideContext } from 'aurelia-binding';

// from https://github.com/aurelia/templating/issues/411
@templateController
@inject(BoundViewFactory, ViewSlot)
class OwnContextCustomAttribute {
    constructor(factory, slot) {
        this.factory = factory; 
        this.slot = slot;
    }

    bind(bindingContext, overrideContext) {
        let newContext = { };
        overrideContext = createOverrideContext(newContext, overrideContext); 

        if (!this.view) {
            this.view = this.factory.create(); 
            this.view.bind(newContext, overrideContext); 
            this.slot.add(this.view); 
        } else { 
            this.view.bind(newContext, overrideContext); 
        } 
    }

    unbind() {
        if (this.view)
            this.view.unbind();
    }
}

更新

我似乎有所作为。我打了补丁aurelia/templating-resources/css-resource.js

 beforeCompile(content: DocumentFragment, resources: ViewResources, instruction: ViewCompileInstruction): void {
+  if (this.done) {
+      return
+  } else {
+      this.done = true
+  }
   if (instruction.targetShadowDOM) {
     DOM.injectStyles(this.css, content, true);
   } else if (FEATURE.scopedCSS) {
     let styleNode = DOM.injectStyles(this.css, content, true);
     styleNode.setAttribute('scoped', 'scoped');
   } else if (!this.owner._alreadyGloballyInjected) {
     DOM.injectStyles(this.css);
     this.owner._alreadyGloballyInjected = true;
   }
 }

0 个答案:

没有答案