我有一个指令,它有一个掩码和输入控件的验证。它基本上是一个时间输入,用户可以输入45(45分钟)或2.5(2.5小时=> 150分钟)之类的东西。编辑时输入为type=number
,使用过滤器显示结果时输入为type=text
。
(仅允许增加15分钟,并且过滤器应用于模糊事件)
所有工作正常除了我点击文本框时的初始值丢失。在focus
事件中,scope.minutes
值未定义,其中应该是控制器中设置的90
值。我无法弄清楚原因。
angular.module('demoApp', [])
.controller('MainController', MainController)
.filter("hoursMinutes", function () {
return function (mins) {
if (mins == 0) return "0 mins";
var hours = ((mins - (mins % 60)) / 60);
var minutes = (mins % 60);
return (hours > 0 ? hours + " hr" + (hours === 1 ? "" : "s") : "") + (minutes > 0 ? " " + minutes + " min" + (minutes === 1 ? "" : "s") : "");
}
})
.directive("ixTimeEntry", function ($filter) {
return {
restrict: "A",
require: 'ngModel',
scope: {
minutes: "=",
filter: "@",
inputFormat: "@"
},
link: function (scope, element, attr, ngModel) {
// could set a max attribute, so mins can't be more than 1440 (a day)?
var inputFormat = scope.inputFormat || "minutes";
var filter = scope.filter || "hoursMinutes";
// for DOM -> model validation
ngModel.$parsers.unshift(function (value) {
var result = validate(value);
ngModel.$setValidity('ixTimeEntry', result.valid);
return result.value;
});
// for model -> DOM validation
ngModel.$formatters.unshift(function (value) {
ngModel.$setValidity('ixTimeEntry', true);
return $filter(filter)(value);
});
function validate(input) {
var result = { valid: false, value: input };
if (input === undefined) return result;
input = +input;
if (input === 0) return result;
if (input < 0) return result;
if (inputFormat === "minutes") {
// entering as minutes:
// if 15, 30, 45, 60, 75, 90, etc => treat as minutes
// if .25, .5, .75, 1, 1.25, ...12 => treat as hours
// else (e.g. 13, 14, 16, 17, 18, etc) => invalid
if (input % 15 === 0) result = { valid: true, value: input };
if (input % .25 === 0 && input <= 12) result = { valid: true, value: input * 60 };
} else if (inputFormat === "hours") {
// entering as hours:
// if .25, .5, .75, 1, 1.25, etc => treat as hours
// else => invalid
if (input % .25 === 0) result = { valid: true, value: input * 60 };
} else {
throw "Invalid inputFormat in timeEntry";
}
return result;
}
function addMask(text) {
return $filter(filter)(text);
}
function removeMask(text) {
if (inputFormat === "hours")
return +text / 60;
return text;
}
element.val(addMask(scope.minutes));
element.bind("blur", function () {
element.attr("type", "text");
scope.$apply(function () {
var value = validate(element.val()).value;
scope.minutes = value;
element.val(addMask(value));
});
});
element.bind("focus", function () {
element.attr("type", "number");
scope.$apply(function () {
element.val(removeMask(scope.minutes));
});
});
}
};
});;
function MainController() {
var vm = this;
vm.minutes1 = 90;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="MainController as vm">
<form id="timeForm" name="timeForm" >
<input type="text" class="form-control" name="time" placeholder="time" ix-time-entry input-format="minutes" minutes="vm.minutes" filter="hoursMinutes" ng-required="true" ng-model="vm.minutes1" />
</form>
<br>
Model: {{vm.minutes1}}<br>
Valid: {{timeForm.time.$valid}}<br>
</div>
&#13;
答案 0 :(得分:1)
您只在vm.minutes1 = 90;
中设置了MainController
。如果你也设置vm.minutes = 90;
,它也可以。
angular.module('demoApp', [])
.controller('MainController', MainController)
.filter("hoursMinutes", function () {
return function (mins) {
if (mins == 0) return "0 mins";
var hours = ((mins - (mins % 60)) / 60);
var minutes = (mins % 60);
return (hours > 0 ? hours + " hr" + (hours === 1 ? "" : "s") : "") + (minutes > 0 ? " " + minutes + " min" + (minutes === 1 ? "" : "s") : "");
}
})
.directive("ixTimeEntry", function ($filter) {
return {
restrict: "A",
require: 'ngModel',
scope: {
minutes: "=",
filter: "@",
inputFormat: "@"
},
link: function (scope, element, attr, ngModel) {
// could set a max attribute, so mins can't be more than 1440 (a day)?
var inputFormat = scope.inputFormat || "minutes";
var filter = scope.filter || "hoursMinutes";
// for DOM -> model validation
ngModel.$parsers.unshift(function (value) {
var result = validate(value);
ngModel.$setValidity('ixTimeEntry', result.valid);
return result.value;
});
// for model -> DOM validation
ngModel.$formatters.unshift(function (value) {
ngModel.$setValidity('ixTimeEntry', true);
return $filter(filter)(value);
});
function validate(input) {
var result = { valid: false, value: input };
if (input === undefined) return result;
input = +input;
if (input === 0) return result;
if (input < 0) return result;
if (inputFormat === "minutes") {
// entering as minutes:
// if 15, 30, 45, 60, 75, 90, etc => treat as minutes
// if .25, .5, .75, 1, 1.25, ...12 => treat as hours
// else (e.g. 13, 14, 16, 17, 18, etc) => invalid
if (input % 15 === 0) result = { valid: true, value: input };
if (input % .25 === 0 && input <= 12) result = { valid: true, value: input * 60 };
} else if (inputFormat === "hours") {
// entering as hours:
// if .25, .5, .75, 1, 1.25, etc => treat as hours
// else => invalid
if (input % .25 === 0) result = { valid: true, value: input * 60 };
} else {
throw "Invalid inputFormat in timeEntry";
}
return result;
}
function addMask(text) {
return $filter(filter)(text);
}
function removeMask(text) {
if (inputFormat === "hours")
return +text / 60;
return text;
}
element.val(addMask(scope.minutes));
element.bind("blur", function () {
element.attr("type", "text");
scope.$apply(function () {
var value = validate(element.val()).value;
scope.minutes = value;
element.val(addMask(value));
});
});
element.bind("focus", function () {
element.attr("type", "number");
scope.$apply(function () {
element.val(removeMask(scope.minutes));
});
});
}
};
});;
function MainController() {
var vm = this;
vm.minutes = 90;
vm.minutes1 = 90;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="MainController as vm">
<form id="timeForm" name="timeForm" >
<input type="text" class="form-control" name="time" placeholder="time" ix-time-entry input-format="minutes" minutes="vm.minutes" filter="hoursMinutes" ng-required="true" ng-model="vm.minutes1" />
</form>
<br>
Model: {{vm.minutes1}}<br>
Valid: {{timeForm.time.$valid}}<br>
</div>