如何在AngularJS中实现组件组成(类似于React渲染道具模式)?

时间:2018-12-28 13:55:37

标签: javascript angularjs reactjs components angularjs-ng-transclude

我正在尝试在AngularJS中创建一个网格组件,并在运行时提供其网格项。 (想想React中的渲染道具模式)。

我正在尝试使用“新的” AngularJS组件API以及包含功能来构建它。

<grid-items>
   <grid-item-type-1></grid-item-type-1>
</grid-items>


<grid-items>
   <grid-item-type-2></grid-item-type-2>
</grid-items>

任何这些都应该有效。 <grid-items>应该注意数据,而<grod-item-type-x>应该注意如何分发每个单独的项目。

2 个答案:

答案 0 :(得分:0)

研究之后,我发现了两种方法。其中之一是require子组件中的父控制器并使用其数据,或者通过将链接功能与编译一起使用(这不适用于组件API),如下所示:

link: function(scope, element) {
      scope.items.forEach((item) => {
        const tpl = "<" + item.type + " item=" + item + " ></grid-item>"
        const child = $compile(tpl)(item)
        element.append(child);
      });
    }

上述方法不使用包含,但您仍可以使用在运行时提供给父级的任何子级组件。

答案 1 :(得分:0)

好吧,如果我正确理解的话,有一些方法可以做到这一点。定义组件时,如下所示:

{
  restrict: 'E',
  bindings: {
    myProp: '@',
  },
  transclude: {
    'myTransclude': 'myTransclude',
  },
  template,
  controller,
  controllerAs: 'ctrl',
}

您传递给bindings的任何内容都可以从您的组件中访问。因此,在上面的示例中,如果您执行了以下操作:<my-component my-prop="hey" />,那么您也可以访问ctrl.myProp并获得hey的值。

在更复杂的方式下,您可以使用包含在myComponent模板中的包含项:

  <div ng-transclude="myTransclude"></div>

,每次使用时都会像这样:

<my-component>
    <my-transclude>
        <!-- whatever you wan to go inside your component  -->
    </my-transclude>
</my-component>

当然,您可以有一个HTML编译指令(建议您搜索现有指令),在那里可以使用模板并使用它

    <div html-compile-directive="ctrl.myTemplate"></div>