我正在尝试将动态变量传递给显示时间选择器的指令(pickadate.js:http://amsul.ca/pickadate.js/time/)。但是,我正在努力研究如何将选项纳入指令。我在互联网上搜索,但看到了很多方法,并且很困惑如何最好地构建它,因为它不起作用。这是我目前的代码:
指令:
// Pick a date directive used as pick-a-time on HTML element
appDirectives.directive('pickATime', function() {
return {
// Restrict it to be an attribute in this case
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function(scope, element, attrs) {
element.pickatime(scope.$eval(attrs.pickATime));
},
scope: {
timeOptions: '=options'
},
templateUrl: '../Templates/timeoptions.html'
};
});
指令模板:
Min: {{timeOptions.startTime}} Max: {{customerInfo.endTime}}
HTML:
<input type="text" placeholder="Start Time" id="timestart" pick-a-time options="timeRange" data-ng-model="itemtimestart" class="form-control" autocomplete="off">
传递动态值的控制器(存储在REST中)
// Query settings for variables to be used later in function
appSettings.query(function(settings) {
// Data is within an object of "value", so this pushes the server side array into a variable
var setting = settings.value;
// Foreach result, where setting is equal to active get the apporpriate variables
angular.forEach(setting, function(settingvalue, settingkey) {
if (settingvalue.Title == 'Active') {
// Get work and non work durations as variables
workDuration = settingvalue.Work_x0020_Day_x0020_Hours_x0020;
nonWorkDuration = settingvalue.Non_x0020_Work_x0020_Day_x0020_H;
// Get $scope variables to control time picker range
var startHour = settingvalue.Work_x0020_Day_x0020_Start_x0020.split(":")[0];
var startMinute = settingvalue.Work_x0020_Day_x0020_Start_x0020.split(":")[1];
var startTime = '[' + startHour + ',' + startMinute + ']';
var endHour = settingvalue.Work_x0020_Day_x0020_End_x0020_M.split(":")[0];
var endMinute = settingvalue.Work_x0020_Day_x0020_End_x0020_M.split(":")[1];
var endTime = '[' + endHour + ',' + endMinute + ']';
$scope.timeRange = {min: startTime, max: endTime};
}
})
});
输入的非动态方法(有效)如下:
<input type="text" placeholder="End Time" id="timeend" pick-a-time="{min: [0,0], max: [23,30]}" data-ng-model="itemtimeend"class="form-control" autocomplete="off">
更新:与Dave合作,我已调整为以下内容。它正确记录timeRange,但为指令
中的timeOptions提供了未定义的内容timeRange日志:
time start is [8,30]time end is [17,0]
timeOption log:
time options log undefined
指令(在日志记录中未定义timeOptions):
appDirectives.directive('pickATime', function() {
return {
// Restrict it to be an attribute in this case
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function(scope, element, attrs) {
element.pickatime(scope.pickATime);
console.log("time options log" + scope.timeOptions);
},
scope: {
timeOptions: '='
},
templateUrl: '../Templates/timeoptions.html'
};
});
模板:
min: {{timeOptions.min}}, max: {{timeOptions.max}}
控制器(正确注销):
// Get $scope variables to control time picker range
var startHour = settingvalue.Work_x0020_Day_x0020_Start_x0020.split(":")[0];
var startMinute = settingvalue.Work_x0020_Day_x0020_Start_x0020.split(":")[1];
var startTime = '[' + startHour + ',' + startMinute + ']';
var endHour = settingvalue.Work_x0020_Day_x0020_End_x0020_M.split(":")[0];
var endMinute = settingvalue.Work_x0020_Day_x0020_End_x0020_M.split(":")[1];
var endTime = '[' + endHour + ',' + endMinute + ']';
$scope.timeRange = {
min: startTime,
max: endTime
};
HTML:
<input type="text" placeholder="Start Time" id="timestart" pick-a-time timeOptions="timeRange" data-ng-model="itemtimestart" class="form-control" autocomplete="off">
更新 - Picker Working ...但现在表单没有提交时间数据按照此帖子:TimePicker directive won't submit time (undefined) **
非常感谢@ dave-alperovich和@ joe-enzminger的不懈帮助和出色的答案。
控制器:
// Get $scope variables to control time picker range
var startHour = settingvalue.Work_x0020_Day_x0020_Start_x0020.split(":")[0];
var startMinute = settingvalue.Work_x0020_Day_x0020_Start_x0020.split(":")[1];
var endHour = settingvalue.Work_x0020_Day_x0020_End_x0020_M.split(":")[0];
var endMinute = settingvalue.Work_x0020_Day_x0020_End_x0020_M.split(":")[1];
$scope.timeRange = {
min: [startHour,startMinute],
max: [endHour,endMinute]
};
指令:
appDirectives.directive('pickATime', function() {
return {
// Restrict it to be an attribute in this case
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function(scope, element, attrs) {
element.pickatime(scope.options());
},
scope: {
options: '&pickATime'
},
};
});
用法:
<input ng-if="timeRange" type="text" placeholder="Start Time" id="timestart" pick-a-time="timeRange" data-ng-model="itemtimestart" class="form-control" autocomplete="off">
答案 0 :(得分:3)
将数据从父作用域传递到指令有许多不同的方法。您已经(正确地)选择了孤立范围提供的选择类别,如
所示scope: {
}
指令的参数。这意味着您的指令范围不会原型继承父作用域。
您的第一个示例不起作用的原因是行:
element.pickatime(scope.$eval(attrs.pickATime));
最终将undefined传递给element.pickatime()方法。
这是因为这行代码的作用是尝试根据指令的范围来评估DOM中的pick-a-time html属性值中包含的表达式(这是一个字符串)。第一个示例中,pick-a-time属性的值为空字符串。
当您使用“非动态”版本时,pick-a-time属性的值现在是字符串
"{min: [0,0], max: [23,30]}"
哪个是有效的角度表达式,$ eval将返回一个对象,其最小和最大属性分别设置为[0,0]和[23,30],因此您的指令有效。
在这两种情况下,您的指令都会完全忽略使用options属性传递给指令的值。
一个简单的解决方法是修改您的指令以使用通过options属性传入的信息。编写指令的方式,此对象将与$ scope.timeOptions值双向绑定(稍后将详细介绍)。实质上,对$ scope.timeOptions的任何更改都将显示在父作用域的timeRange属性中,反之亦然。
对指令的更改将是:
element.pickatime(scope.timeOptions);
额外信用:
在上一个示例中,您声明指令中未定义timeOptions。这是因为html需要是:
<input type="text" placeholder="Start Time" id="timestart" pick-a-time time-options="timeRange" data-ng-model="itemtimestart" class="form-control" autocomplete="off">
唯一的变化是timeOptions - &gt;时间的选项
这是角度按惯例处理属性到范围属性映射的方式。
额外额外信用:
您的示例不需要双向绑定(我认为您不想更改指令中的选项)。您可以使用&amp ;;避免创建两个$ watch。而不是=。这将是我的指令的最终版本:
appDirectives.directive('pickATime', function() {
return {
// Restrict it to be an attribute in this case
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function(scope, element, attrs) {
element.pickatime(scope.options());
},
scope: {
options: '&pickATime'
},
templateUrl: '../Templates/timeoptions.html'
};
});
用法:
点符号问题的更新:
在您的控制器中,您需要对itemtimestart使用点表示法:
.controller('xxx', function($scope){
$scope.parameters = {
}
}
<input ng-if="timeRange" type="text" placeholder="Start Time" id="timestart" pick-a-time="timeRange" data-ng-model="parameters.itemtimestart" class="form-control" autocomplete="off">
$scope.paramters.itemtimestart should now be the correct time.
您还可以使用“controller as”语法来简化此操作。
答案 1 :(得分:0)
如果选项已经存在(在timeRange
中)且不会随时间变化,则无需执行任何操作:它应位于scope.timeOptions
(链接和控制器中)。
但是,如果选项可以随时更改,并且您希望在合并时刷新,则需要注意其更改:
scope.$watch('timeOptions', function(newOptions) {
// do something with the newOptions
});