我正在构建某种日期选择器,实际上是2个日期选择器。 一个用于开始日期,另一个用于结束日期。每个datepicker元素生成一个包含2个输入标记的模板()。我想将数据从input的value属性传递给控制器。 我试图在内部范围中定义字段,这些字段是双向数据绑定(dateOne和dateTwo)但显然没有效果,并且在两个字段之间没有传递实际数据。 我的另一种方法是使用ng-model,但我对这个功能没什么好处,我不知道这个规则。 这是我的代码
angular.module('directives', [])
.directive('datepicker', ['$timeout',function ($timeout) {
// Runs during compile
return {
scope: {
id: '@',
"class": '@',
dateOne: '=',
dateTwo: '='
},
restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
template: '<div id="{{id}}" class="{{class}}">'+
'<div class="date-wrapper">'+
'<label for="datepicker-start">From:</label>'+
'<div class="fieldWrapper">'+
'<input id="datepicker-start" type="date" placeholder="Select date" value={{dateOne}} />'+
'<a class="calendar"></a>'+
'</div>'+
'</div>'+
'<div class="date-wrapper">' +
'<label for="datepicker-end">To:</label>' +
'<div class="fieldWrapper">' +
'<input id="datepicker-end" type="date" placeholder="Select date" value={{dateTwo}}/>' +
'<a class="calendar"></a>' +
'</div>' +
'</div>'+
'</div>'
,
replace: true,
link: function($scope, iElm, iAttrs, controller) {
console.log('directive link function');
console.log('directive iAttrs', iAttrs);
$(".date-wrapper").each(function (index) {
console.log('directive index', index);
$input = $(this).find('input');
$btn = $(this).find('.calendar');
console.log('input', $input[0]);
console.log('btn', $btn[0]);
$input.attr('type', 'text');
var pickerStart = new Pikaday({
field: $input[0],
trigger: $btn[0],
container: $(this)[0],
format: 'DD/MM/YYYY',
firstDay: 1
});
$btn.show();
});
}
};
}]);
------------------------更新代码--------------------- --------------
angular.module('directives', [])
.directive('datepicker', ['$timeout',function ($timeout) {
// Runs during compile
return {
scope: {
id: '@',
"class": '@',
dateOne: '=',
dateTwo: '='
},
restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
template: '<div id="{{id}}" class="{{class}}">'+
'<div class="date-wrapper">'+
'<label for="datepicker-start">From:</label>'+
'<div class="fieldWrapper">'+
'<input id="datepicker-start" type="date" placeholder="Select date" ng-model=dateOne />' +
'<a class="calendar"></a>'+
'</div>'+
'</div>'+
'<div class="date-wrapper">' +
'<label for="datepicker-end">To:</label>' +
'<div class="fieldWrapper">' +
'<input id="datepicker-end" type="date" placeholder="Select date" ng-model=dateTwo />' +
'<a class="calendar"></a>' +
'</div>' +
'</div>'+
'</div>'
,
replace: true,
link: function($scope, iElm, iAttrs, controller) {
console.log('directive iAttrs', iAttrs);
$(".date-wrapper").each(function (index) {
console.log('directive index', index);
$input = $(this).find('input');
$btn = $(this).find('.calendar');
console.log('input', $input[0]);
console.log('btn', $btn[0]);
$input.attr('type', 'text');
var pickerStart = new Pikaday({
field: $input[0],
trigger: $btn[0],
container: $(this)[0],
format: 'DD/MM/YYYY',
firstDay: 1
});
$btn.show();
});
$scope.$watch(iAttrs.dateOne, function (newValue, oldValue) {
console.log('newValue', newValue);
console.log('oldValue', oldValue);
}, true);
}
};
答案 0 :(得分:2)
实际上你几乎就在那里,我做了一些与你所描述的非常类似的东西,这是我解决它的方法(在我的例子中我使用了UI-Bootstrap Date选择器)。
从指令向控制器发送数据的方式是使用回调,而不是简单的监视。如果您使用=
,则必须在控制器(和指令)中设置监视以监视值的变化,这是整体和额外代码的不良做法。
基本上你需要做的是
在你的指令定义对象中使用&
符号绑定一个回调方法/函数
scope: {
onSelect: "&" // onSelect is our callback function in the ctrl
}
然后,为回调属性提供一个绑定到控制器$ scope的函数,但是你传递一个函数引用(不是像ng-changed那样的函数调用)。像这样
<my-directive on-selected="onSelected"></my-directive>
然后你定义onSelected
应该做什么,假设我要打印所选日期
// inside controller
$scope.onSelected = function(time) {
console.log("Time selected: ", time);
}
请注意,我们将指令中的time参数传递给控制器,因此scope.onSelect()
实际上是一个curried函数,这意味着它将在调用后返回一个函数(也就是说,如果你提供了一个函数,你可以使用angular.isFunction
)测试它,所以你应该调用curried函数并提供你的参数scope.onSelect()(time)
。
scope.selectDate = function(time) {
if (angular.isFunction(scope.onSelect())) {
// we use isFunction to test if the callback function actually
// points to a valid function object
scope.onSelect()(time); // we pass out new selected date time
}
}
这是一个显示我的意思的plunk。
答案 1 :(得分:0)
使用ng-model = dateOne替换模板中的值,并使用dateTwo替换相同的值。
我建议为此指令使用专用控制器,而不是在链接功能中使用逻辑。
app.directive('someDirective',function(){ 返回{ 限制:'A', controller:'SomeController', controllerAs:'ctrl', 模板:'{{ctrl.foo}}' }; });
在此处阅读更多http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html