1

我正在尝试创建一个包含多个子组件的组件。我正在创建一组指令,我团队中的其他开发人员可以使用这些指令来创建自定义搜索表单。例如,他们会创建如下标记:

<search-panel name="myCustomSearch">
    <search-field name="dates" type="dateRange"></search-field>
    <search-field name="categories" type="categorySelector" data="{{categories}}"></search-field>
</search-panel>

我有一个搜索面板指令和几个搜索字段指令。搜索面板充当容器,每个搜索字段都提供特定类型的字段(日期范围、提前输入、类别选择器等)。每个搜索字段在其范围内都有一个值属性,我试图找出一种方法让父搜索面板指令在其范围内有一个属性,该属性包含所有子搜索字段的键值集合。

我已经正确渲染了两个指令,但我不确定如何让搜索面板知道/可以访问所有子组件。

4

4 回答 4

2

您可以在search-field指令中要求search-panel控制器使用require:'^searchPanel'

然后在链接函数中,您将拥有到该控制器的链接,因此这些指令可以将自己添加到某个数组中(我假设每个搜索字段都有其隔离范围):

link: function(scope, elem, attrs, spCtrl) {
  spCtrl.fields.push({name: attrs.name, scope: scope});
}

(当然,您可以添加的不是整个范围,而是一些对象,然后观察更改并更新该对象的值字段。

于 2013-04-22T19:39:40.750 回答
0

我的复合组件(多个嵌入指令)的实现基于以下思想:

  • 使用一个指令捕获子组件 $transclude
  • 用另一个指令输出这个子组件

现场演示http://nickholub.github.io/angular-composite-component/#/

演示源代码https://github.com/nickholub/angular-composite-component

指令源代码https://github.com/nickholub/angular-composite-component/blob/master/app/directive/angular-composite-component.js

<div cs-composite>
    <div cs-section="header">
        Composite Component Header
    </div>
    <div cs-section="footer">
        Composite Component Footer
        <div>Random Value: {{randomValue}}</div>
        <div>Percentage: {{percentage}}%</div>
    </div>
</div>

捕获内容的指令

.directive('csSection', function () {
    return {
      transclude: 'element',
      priority: 100,
      require: '^csComposite',
      link: function (scope, element, attrs, ctrl, $transclude) {
        var directiveTransclude = {
          id: attrs.csSection,
          transclude: $transclude,
          element: element
        };

        ctrl.registerTransclude(directiveTransclude);
      }
    };
  })

输出内容的指令

.directive('csTransclude', function () {
    return {
      transclude: true,
      link: function (scope, element, attrs) {
        var id = attrs.csTransclude;
        var directiveTransclude = scope.transcludes[id];
        if (directiveTransclude) {
          var selectedScope = scope.$new();
          directiveTransclude.transclude(selectedScope, function (clone) {
            element.append(clone);
          });
        }
      }
    };
  })
于 2014-07-10T19:05:48.987 回答
0

Mark Rajcok 在这里有一个很好的 stackoverflow 答案:

AngularJS 指令控制器需要父指令控制器?

带有指向这个非常清晰的 jsFiddle 的链接:http: //jsfiddle.net/mrajcok/StXFK/

<div ng-controller="MyCtrl">
    <div screen>
        <div component>
            <div widget>
                <button ng-click="widgetIt()">Woo Hoo</button>
            </div>
        </div>
    </div>
</div>

JavaScript 在 jsFiddle 中。

于 2013-04-23T03:21:01.050 回答
0

这里的基本思想是在两者之间创建一个公共控制器,并在指令链接中将它们链接起来。

创建指令时,您可以将控制器传递给第四个参数,如下所示:

app.directive('myDirective', function(){
  return {
    scope: true,
    link: function postLink( scope, element, attrs, ctrls ){
      //check ctrls for common link
    }
  }
}

在 angularui/bootstrap 项目中创建的一个很好的例子是Tabs 指令,它有一个通用控制器将它们链接起来,作为从哪里开始的例子。

希望这可以帮助。

于 2013-04-22T19:45:50.250 回答