eme*_*his 9 javascript angularjs angularjs-directive
我有一个表单输入,用于MySQL日期字段.例如:2015-01-31.
我想允许用户使用3种不同的表单输入来输入它.一年一个,一个月一个,一天一个.
显然ng-model不会开箱即用,因为我试图将日期字符串的一部分绑定到每个输入.我很确定这样做的方法就是创建三个"临时"范围变量/模型
$scope.year;
$scope.month;
$scope.day;
Run Code Online (Sandbox Code Playgroud)
...然后以某种方式将它们组合/绑定到实际值.
//If only it were this easy!
$scope.date = $scope.year + "-" + $scope.month + "-" + $scope.day;
Run Code Online (Sandbox Code Playgroud)
当然,上面的行不起作用,因为值不是双向约束的.如果表单仅用于保存新数据,我可以通过组合提交输入来逃避.但我需要它来处理/显示现有数据.如果我无法找到一种方法来纠结Angular的绑定魔法来做我想做的事情,那将会变得非常丑陋.
我发现这个问题我认为它试图做同样的事情,但他们用自定义指令解决它,这是我希望避免的.我知道这可能是一种更易于维护/可移植/模块化的方式,但我是Angular的新手并且有点害怕.此外,输入使用可爱的角度选择指令,这为该方法增加了额外的复杂性.
tyd*_*otg 11
指令可能是最好的,但这些示例看起来过于复杂.无论如何,如果您希望避免使用指令,只需$scope.$watch在每次更新其中一个重要变量时使用并重新构建日期字符串.
这样的东西可能在你的控制器中:
$scope.year = '';
$scope.month = '';
$scope.day = '';
// this might be able to be refactored
$scope.$watch('year', buildDate);
$scope.$watch('month', buildDate);
$scope.$watch('day', buildDate);
function buildDate() {
$scope.date = $scope.year + "-" + $scope.month + "-" + $scope.day;
}
Run Code Online (Sandbox Code Playgroud)
作为旁注,这可能是我的指令逻辑也是如此.
编辑:代码清理和小提琴
更清洁的例子 - 我更喜欢这个,因为它将所有与日期相关的项目与一个对象组合在一起,这也使得更容易观察更改.
$scope.date = {
year: '',
month: '',
day: ''
};
// use watch collection to watch properties on the main 'date' object
$scope.$watchCollection('date', buildDate);
function buildDate(date) {
$scope.dateString = date.year + "-" + date.month + "-" + date.day;
}
Run Code Online (Sandbox Code Playgroud)
这是一个有趣的演示,它使用的自定义指令比你链接的指令要吓人得多.您应该能够将它们应用到您的输入中,而不会与其他内容发生太多冲突:
http://plnkr.co/edit/3a8xnCfJFJrBlDRTUBG7?p=preview
诀窍是使用该指令为模型设置解析器和格式化程序.这使您可以拦截对模型的更改并与范围的其余部分进行交互:
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.date = new Date();
});
app.directive('datePartInput', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, ngModel) {
var part = attrs.part;
var modelToUser, userToModel
console.log('part:', part);
if (part == 'year') {
modelToUser = function(date) {
return date.getFullYear();
}
userToModel = function(year) {
ngModel.$modelValue.setYear(year);
return ngModel.$modelValue
}
}
else if (part == 'month') {
modelToUser = function(date) {
return date.getMonth();
}
userToModel = function(month) {
ngModel.$modelValue.setMonth(month);
return ngModel.$modelValue;
}
}
else if (part == 'day') {
modelToUser = function(date) {
return date.getUTCDate();
};
userToModel = function(day) {
ngModel.$modelValue.setUTCDate(day);
return ngModel.$modelValue;
};
}
ngModel.$formatters.push(modelToUser);
ngModel.$parsers.push(userToModel);
}
}
})
Run Code Online (Sandbox Code Playgroud)
和模板:
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
{{date | date}}
<input date-part-input part="year" ng-model="date">
<input date-part-input part="month" ng-model="date">
<input date-part-input part="day" ng-model="date">
</body>
Run Code Online (Sandbox Code Playgroud)