1

当我在 Angular.dart 中创建一个组件时

library main;

import 'package:angular/angular.dart';
import 'package:di/di.dart';

class Item {
  String name;
  Item(this.name);
}

@NgComponent(
    selector: 'my-component',
    publishAs: 'ctrl',
    applyAuthorStyles: true,
    template: '''<div ng-repeat="value in ctrl.values"><span>{{value.name}}</span> - <content><content></div>'''
)

class MyComponent {
  List<Item> values = [new Item('1'), new Item('2'), new Item('3'), new Item('4')];

  MyComponent() {
    print('MyComponent');
  }
}


class MyAppModule extends Module {
  MyAppModule() {
    type(MyComponent);
  }
}

void main() {
  ngBootstrap(module: new MyAppModule());
}

并像使用它一样

<!DOCTYPE html>

<html ng-app>
  <head>
    <meta charset="utf-8">
  </head>

  <body>

    <h3>Repeat</h3>
    <my-component>
      <div>some provided content to repeat</div>
    </my-component>

    <script type="application/dart" src="index.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

我明白了

在此处输入图像描述

我知道<content>标签在 Web 组件中不是这样工作的。

但是有没有其他方法,我可以在我的组件中进行一些操作,以<div>重复提供作为子元素提供的内容?

4

2 回答 2

1

我没有答案,我现在无法测试我的建议,但尝试在 MyComponent 中注入元素、编译器、范围和块工厂:

Element element;
Compiler compiler;
Injector injector;
Scope scope;

MyComponent(this.element, this.compiler, this.injector, this.scope) {
}

您可以将 div 作为“元素”的子项访问。

然后你不使用 NgComponent 的模板,而是从一个字符串构建你自己的模板,插入孩子并编译它:

String template = '''<div ng-repeat="value in ctrl.values"><span>{{value.name}}</span> - <div id="inner"><div></div>''';

void onShadowRoot(ShadowRoot shadowRoot) {
  List<DivElement> children = element.children;
  shadowRoot.appendHtml(template);    
  DivElement inner = shadowRoot.querySelector('#inner');
  inner.children.add(children);  
  BlockFactory fact = compiler([shadowRoot]);
  Scope childScope = scope.$new();
  Injector childInjector = 
      injector.createChild([new Module()
      ..value(Scope, childScope)]);
  fact(childInjector, children);
}

也许它会给你正确的方向。

于 2014-01-18T19:08:35.463 回答
1

我像这样解决了

代码<my-component>

@NgComponent(
    selector: 'my-component',
    publishAs: 'ctrl',
    template: '''<div ng-repeat="value in ctrl.values"><span ng-bind-nodes="ctrl.nodes"></span><span>something hardcoded: {{value.name}}</span></div><content id='content'></content>'''
)

class MyComponent extends NgShadowRootAware {
  List<Item> values = [new Item('1'), new Item('2'), new Item('3'), new Item('4')];

  List<dom.Node> nodes = new List<dom.Node>();

  MyComponent();

  @override
  void onShadowRoot(dom.ShadowRoot shadowRoot) {
    nodes.addAll((shadowRoot.querySelector('#content') as dom.ContentElement).getDistributedNodes());
    //nodes.forEach((n) => print(n));
    nodes.forEach((n) => n.remove());
  }
}

该组件删除它的子节点并在字段节点中提供它们

指令ng-bind-nodes 将节点添加到应用它的元素

@NgDirective(
  selector: '[ng-bind-nodes]',
  publishAs: 'ctrlx' // conflicts with my-component
)
class NgBindNodesDirective {
  dom.Element _element;
  MyComponent _myComponent;
  Scope _scope;
  Compiler _compile;
  Injector _injector;

  NgBindNodesDirective(this._element, this._myComponent, this._scope, this._compile, this._injector);

  @NgOneWay('ng-bind-nodes') set nodes(var nodes) {
    print(nodes);
    if(nodes == null) {
      return;
    }
    _element.nodes.clear();
    nodes.forEach((dom.Node node) {
      _element.nodes.add(node.clone(true));
    });

    BlockFactory template = _compile(_element.nodes);
    Block block = template(_injector, _element.nodes);
  }
}
于 2014-01-22T10:42:01.683 回答