2013-06-01 125 views
4

我试图想出一个可重用指令库。我试图实现的前两个指令是DatePicker和DateRangePicker。 DateRangePicker必须包含两个DatePickers。创建包含其他指令的Angular.js指令

我想要的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和结束日期

我看了几个如何创建指令的例子,但我不知道如何将参数传递到基本指令。这里是显示适当的值theIdtheLabel但不显示正确的日期的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']; 
     } 
     }; 
    }); 

的代码。

这是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"; 

     } 
     }; 
    }); 

任何人都可以指出我的解决方案吗?我在DateRangePicker的link()方法之前调用了基础DatePickers的link()方法。因此难怪价值观没有通过。但我缺乏整体的概念理解来解决问题。官方文件没有多大帮助。

一般来说,有没有人试图达到类似的目标 - 在其他指令之上构建指令,并通过这样做,构建一个业务领域特定的组件库?

+0

http://www.youtube.com/watch?feature=player_embedded&v=WqmeI5fZcho#! 这是一个不错的视频,它很好的阐明了 – mkvakin

+0

为什么不使用Element指令而不是Attribute? –

回答

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) {} 
    }; 
}); 
3

这一点正确地使用范围。 @属性只是静态地从标签属性中复制值,而应该使用链接父范围变量与指令范围变量的属性=。 我创建了this plunker以向您展示如何正确实现这两个指令。