重复作为内容提供的元素

时间:2014-01-16 08:41:02

标签: dart angular-dart

当我在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>

我得到了

enter image description here

我知道<content>标记在网络组件中不起作用。

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

2 个答案:

答案 0 :(得分:1)

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

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

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

您可以将div作为'element'的子级访问。

然后你不使用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);
}

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

答案 1 :(得分: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);
  }
}