我的网络应用程序中有来自/迄今为止的选择,如下所示:
<div class="date-picker-horizontal">
<i class="icon-calendar"></i>
Select Date:
<input bs-datepicker type="text" ng-model="fromDate" /> to
<input bs-datepicker type="text" ng-model="toDate" />
<a class="btn" ng-click="loadData()"><i class="icon-refresh"></i></a>
<div class="loading" ng-show="isLoading"></div>
</div>
我需要在我的网络应用中的多个地方使用它,所以我创建了它作为指令,它正在工作。我从范围传递值,如下:
<div ng-controller="myController">
<from-to-date-selector data-from-date="fromDate" data-to-date="toDate" data-on-refresh="loadData()" data-is-loading="isLoading" />
<from-to-date-selector data-from-date="lastYearsDate" data-to-date="thisYearsData" data-on-refresh="loadYearlyData()" data-is-loading="isYearlyLoading" />
</div>
我的控制器“myController”的范围包含传递给指令的每个变量(fromDate,toDate,lastYearsDate等)以及加载数据的函数(loadData(),loadYearlyData())。
我想我想知道这是否是正确的做法?我对Angular很新,并且不想从养成坏习惯开始。是否将一大堆值传递给指令性的不良做法?
答案 0 :(得分:0)
我认为将变量发送到指令没有任何问题,但是我可能不会将“loadYearlyData()”作为要执行的函数发送。这听起来应该在父范围内,并且可以在将来进行操作。复杂数据也倾向于大幅降低指令的可重用性。
我花了相当多的时间来构建我公司网站的日期范围指令。我把它放在这里,因为看到另一种方法可能会有用。
注意:这可能不是一个完美的答案。它提供了想法和见解。
一些警告:
日期范围指令模板
<div class="date-group">
<input type="text" name="dateRangeStartsAt" ng-model="dateRangeStartsAt" date-start-date="dateRangeMinDate" date-end-date="dateRangeMaxDate" date-time required>
<span class="text-small text-minor">- to -</span>
<input type="text" name="dateRangeEndsAt" ng-model="dateRangeEndsAt" date-start-date="dateRangeMinDate" date-end-date="dateRangeMaxDate" date-time required>
</div>
日期范围:
ngApp.directive("uiDateRange", function($timeout) {
return {
templateUrl: '/assets/partials/date-range-directive.html',
scope: {
'dateRangeStartsAt': '=',
'dateRangeEndsAt': '=',
'dateRangeMinDate': '=',
'dateRangeMaxDate': '=',
'dateRangeForm': '=',
'onDateChange': '&',
'hideTime': '='
},
link: function(scope, element, attrs) {
scope.$watch('dateRangeStartsAt+dateRangeEndsAt', function(newValue, oldValue) {
// console.log("Change in date", scope.dateRangeStartsAt, scope.dateRangeEndsAt);
if (scope.dateRangeStartsAt && scope.dateRangeEndsAt) {
var startsAt = _.isNumber(scope.dateRangeStartsAt) ? scope.dateRangeStartsAt : moment.utc(scope.dateRangeStartsAt + " UTC").valueOf();
var endsAt = _.isNumber(scope.dateRangeEndsAt) ? scope.dateRangeEndsAt : moment.utc(scope.dateRangeEndsAt + " UTC").valueOf();
var isValid = startsAt < endsAt;
if (scope.dateRangeMinDate && isValid) isValid = startsAt >= scope.dateRangeMinDate;
if (scope.dateRangeMaxDate && isValid) isValid = endsAt <= scope.dateRangeMaxDate;
if(scope.onDateChange) scope.onDateChange();
setValidity(isValid);
} else {
setValidity(true);
}
});
function setValidity(isValid) {
element.find(".date-group").toggleClass("ng-invalid", !isValid);
if (scope.dateRangeForm && scope.dateRangeForm.dateRangeStartsAt) scope.dateRangeForm.dateRangeStartsAt.$setValidity("dateRange", isValid);
}
}
}
});
日期时间:
ngApp.directive('dateTime', function($timeout) {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
if (!ngModel) {
console.warn('no model, returning');
return;
}
var startDate = scope.$eval(attrs.dateStartDate);
var endDate = scope.$eval(attrs.dateEndDate);
var api;
// element.datetimepicker({
$timeout(function () {
element.datetimepicker({
format: "mm/dd/yyyy hh:ii"
, autoclose: true
// , startDate: (startDate) ? new Date(startDate) : null
// , endDate: (endDate) ? new Date(endDate) : null
, pickerPosition: 'bottom-left'
});
});
// Angular doesn't update val, do it manually
if(scope.$eval(attrs.ngModel)) {
render();
}
scope.$watch(attrs.ngModel, function (newValue) {
render();
});
element.bind('blur keyup change changeDate', function() {
scope.$apply(read);
});
read();
function read() {
ngModel.$setViewValue(element.val());
}
function render() {
var date = scope.$eval(attrs.ngModel);
// Convert timestamp to string date
if(_.isNumber(date)) date = moment.utc(scope.$eval(attrs.ngModel)).format("MM/DD/YYYY HH:mm");
element.val(date);
}
}
}
});