4

我正在尝试提出一个可重用指令库。我尝试实现的前两个指令是 DatePicker 和 DateRangePicker。DateRangePicker 必须包含两个 DatePicker。

我希望 DatePicker 的签名类似于:

<div cx-date-picker="" cx-label="myLabel" 
     cx-id="myDate" cx-source="myDateVarInScope"></div>

我希望 DateRangePicker 看起来像这样:

<div cx-date-range-picker cx-id="searchRangePicker" 
     cx-source="myDateRangeInScope"></div>

其中 myDateRangeInScope 包含成员:​​startDate 和 endDate

我查看了一些如何创建指令的示例,但我不知道如何将参数传递给底层指令。这是 DatePicker 的代码

angular.module('ng').directive('cxDatePicker', function () {
      return {
        restrict: 'A',
        scope: 'isolate',
        template: '<div class="control-group input-append">' +
        '<label for="{{theId}}" class="label">{{theLabel}}</label>' +
        '<input id="{{theId}}" class="input-small" type="text" ' + 
        'ng-model="theSource" data-date-format="dd/mm/yyyy" bs-datepicker>' +
        '<button type="button" class="btn" data-toggle="datepicker">' +
        '<i class="icon-calendar"></i></button>' +
        '</div>',

        link: function (scope, iterStartElement, attr) {
          var theId = attr['cxId'];
          scope.theLabel = attr['cxLabel']
          scope.theId = attr['cxId'];
          scope.theSource = attr['cxSource'];
        }
      };
    });

它显示了theIdtheLabel的正确值,但不显示正确的日期。

这是 DateRangePicker 的代码,它无法为基础 DatePickers 设置属性。

angular.module('ng').directive('cxDateRangePicker', function () {
      return {
        restrict: 'A',
        scope: 'isolate',
        template: '<div cx-date-picker="" cx-source="{{startSource}}" ' +
          'cx-label="{{fromLabel}}" cx-id="{{startId}}"></div>' +
          '<div cx-date-picker="" cx-source="{{endSource}}" cx-label="{{toLabel}}" ' +
          ' cx-id="{{endId}}"></div>',
        link: function (scope, iterStartElement, attr) {
          var theId = attr['cxId'];
          scope.startId = theId + "From";
          scope.endId = theId + "To";
          scope.fromLabel = "From";
          scope.toLabel = "To";
          scope.startSource = attr['cxSource'] + ".startDate";
          scope.endSource = attr['cxSource'] + ".endDate";

        }
      };
    });

谁能指出我的解决方案?我看到底层 DatePickers 的 link() 方法在 DateRangePicker 的 link() 方法之前被调用。因此,难怪这些值没有通过。但我缺乏解决问题的整体概念理解。官方文档并没有太大帮助。

一般来说,有没有人尝试实现类似的目标——在其他指令之上构建指令,并通过这样做来构建特定于业务领域的组件库?

4

2 回答 2

3

关键在于正确使用范围。@属性只是静态地从标记属性复制值,而不是您应该使用=属性将父范围变量与指令范围变量链接起来。我创建了这个 plunker来向您展示如何正确实现这两个指令。

于 2013-06-01T07:16:48.493 回答
0

诀窍在于处理范围。这意味着 Angular.js 确实有一个健全的组件架构,允许在较小的组件之上构建更大的组件。与 Backbone 相比,这是一个很好的进步。我想知道 Ember.js 是否具有类似的功能。

angular.module('ng').directive('cxDatePicker', function () {
  return {
    restrict: 'A',
    scope: 
      {
        cxLabel: '@',
        cxId: '@',
        cxSource: '='
      },
    template: '<div class="control-group input-append">' +
    '<label for="{{cxId}}" class="label" style="margin-right: 6px;">{{cxLabel}}</label>' +
    '<input id="{{cxId}}" class="input-small" type="text" ng-model="cxSource" data-date-format="dd/mm/yyyy" bs-datepicker>' +
    '<button type="button" class="btn" data-toggle="datepicker"><i class="icon-calendar"></i></button>' +
    '</div>',

    link: function (scope, iterStartElement, attr) {}
  };
});


angular.module('ng').directive('cxDateRangePicker', function () {
  return {
    restrict: 'A',
    scope: 
      {
        cxId: '@',
        cxSource: '='
      },
    template: '<div cx-date-picker="" cx-source="cxSource.startDate" cx-label="From" cx-id="{{cxId}}From" ></div>' +
      '<div cx-date-picker="" cx-source="cxSource.endDate" cx-label="To" cx-id="{{cxId}}To" ></div>',
    link: function (scope, iterStartElement, attr) {}
  };
});
于 2013-06-01T06:53:30.240 回答