我有一个表单,我需要用户输入一个持续时间,在资源中这被保存为分钟(或毫秒,易于更改)。我需要指令取第二个/毫秒值,然后为分钟,秒和时间创建3个单独的输入。毫秒。
然后,用户可以修改每个组件,然后该指令将使用3个组件的秒/毫秒值更新模型。
我似乎能够获取模型值,创建3个输入并使用moment.js创建单独的时间组件。
指令
angular.module('myExampleApp')
.directive('lapTimeInput', function () {
var tpl = '<div class="lap_time_input"> \
<input ng-model="lap_time.minutes" type="number" class="minutes" placeholder="00" min="0" max="15" step="1"> \
<span class="lap-time-sep">:</span> \
<input ng-model="lap_time.seconds" type="number" class="seconds" placeholder="00" min="0" max="59" step="1"> \
<span class="lap-time-sep">.</span> \
<input ng-model="lap_time.milliseconds" type="number" class="milliseconds" placeholder="000" min="0" max="999" step="1"> \
</div>';
return {
restrict: 'A',
template: tpl,
replace: true,
require: 'ngModel',
scope: {
},
link: function (scope, element, attrs, ngModel) {
if (!ngModel) return;
scope.$watch(function () {
return ngModel.$modelValue;
}, function(newValue) {
// Using moment.js to extract min, sec & ms parts
var duration = moment.duration(newValue, 'seconds');
scope.lap_time = {
minutes: duration.minutes(),
seconds: duration.seconds(),
milliseconds: duration.milliseconds()
}
});
}
};
});
控制器
$scope.lap = Lap.get({ id: 1 }); // $resource contains .lap_time property
// OR
$scope.lap = {
lap_time: 90.999
}
HTML
<input type="text" lap-time-input ng-model="lap.lap_time" />
这个Plunker希望有点清楚
http://plnkr.co/edit/xmNtlItembSUFFZzaT9n?p=preview
现在我甚至不确定我是否已经使用$ watch on ngModel走上了正确的道路,我猜不会。据我所知,我需要指令做三件事:
即使只是朝着正确的方向轻推,也会有很大的帮助
答案 0 :(得分:1)
这是我设法提出的。不是确切的答案,但应该帮助你。
<强>模板强>
更新了模板并将单圈时间作为要通过指令范围检索的属性传递(参见指令部分)
<div lap-time-input="lap.lap_time"></div>
<强>控制器强>
angular.module('myExampleApp')
.controller('myExampleCtrl', function ($scope) {
// This would usually be a $resouce return via a serice
$scope.lap = {
lap_time: 90.999
};
// watch value of lap time change here when you update minute/second/millisecond
$scope.$watch('lap.lap_time', function (newLapTime) {
console.log('newLapTime', newLapTime);
});
});
<强>指令强>
在模板中添加了第二个/毫秒输入字段。你可能不需要它,但我把它放在那里是出于视觉/调试的原因。
angular.module('myExampleApp')
.directive('lapTimeInput', function () {
var tpl = '<div class="lap_time_input"> \
<input ng-model="lapTimeInput" type="number" placeholder="00.00"> \
<input ng-model="lap_time.minutes" type="number" class="minutes" placeholder="00" min="0" max="15" step="1"> \
<span class="lap-time-sep">:</span> \
<input ng-model="lap_time.seconds" type="number" class="seconds" placeholder="00" min="0" max="59" step="1"> \
<span class="lap-time-sep">.</span> \
<input ng-model="lap_time.milliseconds" type="number" class="milliseconds" placeholder="000" min="0" max="999" step="1"> \
</div>';
return {
restrict: 'A',
template: tpl,
replace: true,
scope: {
lapTimeInput: '='
},
link: function (scope) {
// watch for changes in lapTimeInput and update the lap_time model/object
scope.$watch('lapTimeInput', function (newValue) {
var duration = moment.duration(newValue, 'seconds');
scope.lap_time = {
minutes: duration.minutes(),
seconds: duration.seconds(),
milliseconds: duration.milliseconds()
}
});
// watch for changes in the lap_time model/object
scope.$watchCollection('lap_time', function (newTime, oldTime) {
console.log(newTime);
// convert back to lap time with momentjs here
scope.lapTimeInput = moment.duration(newTime, 'seconds').asSeconds();
});
}
};
});
<强> JSFIDDLE 强>
答案 1 :(得分:1)
好的,我已经设法使用ngModel执行此操作而不向控制器添加任何代码,因为我需要在多个位置使用此指令。我也能够进行验证标记。
angular.module('exampleApp')
.directive('lapTimeInput', function () {
var tpl = '<div class="lap-time-input"> \
<div class="input-group"> \
<span class="input-group-addon"><label for="laps">Lap Time</label></span> \
<input ng-model="lap_time.minutes" type="number" class="form-control minutes" name="minutes" placeholder="00" min="0" max="15" step="1"> \
</div> \
<span class="form-control lap-time-sep">:</span> \
<input ng-model="lap_time.seconds" type="number" class="form-control seconds" placeholder="00" min="0" max="59" step="1"> \
<span class="form-control lap-time-sep">.</span> \
<input ng-model="lap_time.milliseconds" type="number" class="form-control milliseconds" placeholder="000" min="0" max="999" step="1"> \
</div>';
return {
restrict: 'A',
template: tpl,
replace: true,
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
if (!ngModel) return;
ngModel.$formatters.unshift(function(modelValue) {
if(!modelValue) return;
var duration = moment.duration(parseInt(modelValue));
return {
minutes: duration.minutes(),
seconds: duration.seconds(),
milliseconds: duration.milliseconds()
};
});
ngModel.$render = function() {
scope.lap_time = ngModel.$viewValue
};
ngModel.$parsers.unshift(function(modelVal) {
var duration = moment.duration(scope.lap_time);
return duration.asMilliseconds();
});
ngModel.$validators.check = function(modelValue, viewValue) {
if(viewValue) {
if(viewValue.minutes === undefined || viewValue.minutes > 15) {
return false;
}
if(viewValue.seconds === undefined || viewValue.seconds > 59) {
return false;
}
if(viewValue.milliseconds === undefined || viewValue.milliseconds > 999) {
return false;
}
}
return true;
};
scope.$watchCollection('lap_time', function(newVal) {
ngModel.$setViewValue(newVal);
});
}
};
});
如果我在这里有问题,我当然欢迎反馈。