我正在努力想出一个可重复使用的指令库。我试图实现的前两个指令是DatePicker和DateRangePicker。 DateRangePicker必须包含两个DatePickers。
我希望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'];
}
};
});
显示 theId 和 theLabel 的正确值,但不显示正确的日期。
这是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 :(得分:3)
重点是正确使用范围。 @ 属性只是静态地复制标记属性中的值,而应使用 = 属性将父范围变量与指令范围变量链接起来。 我创建了this plunker来向您展示如何正确实现这两个指令。
答案 1 :(得分: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) {}
};
});