我想了解AngularJS的工作原理。
我有一个指令count-Date
,用于按月和年计算年龄。
我无法直接写入数据模型,因为我有很多字段,但我想多次使用我的代码。
HTML:
<div>Date of birth first child
month: <input type = "text" id = "MonthFirstChild" ng-model='MonthFirstChild' required maxlength="2" only-Digits month required count-Date>
year: <input type = "text" name='YearFirstChild' ng-model='YearFirstChild' maxlength="4" only-Digits year-Of-Birth required count-Date>
<span ng-model = "AgeFirstChild">{{AgeFirstChild}}</span>
</div>
<div>Date of birth second child
month: <input type = "text" id = "MonthSecondChild" ng-model='MonthSecondChild' required maxlength="2" only-Digits month required count-Date>
year: <input type = "text" name='YearSecondChild' ng-model='YearSecondChild' maxlength="4" only-Digits year-Of-Birth required count-Date>
<span ng-model = "AgeSecondChild">{{AgeSecondChild}}</span>
</div>
JS:
app.directive('countDate', function () {
return {
link: function ($scope, element, attrs) {
element.bind('blur', function(event,el) {
var el = angular.element(element),
month = +el.parent().children().eq(0).val(),
year = +el.parent().children().eq(1).val(),
dateOfBirth = new Date(year,month),
now = new Date(),
today = new Date(now.getFullYear(), now.getMonth()),
age = Math.round((now - dateOfBirth)/(32140800000);
});
}
};
});
我需要帮助重写指令。
答案 0 :(得分:0)
如果你想做的只是计算年龄,写一个指令有点过分 - 你可以简单地写一个计算年龄的范围方法,如:
HTML:
<div>Date of birth first child
month: <input type="number" min="1" max="12" ng-model="MonthFirstChild" required maxlength="2" />
year: <input type="number" min="0" max="9999" ng-model="YearFirstChild" required maxlength="4" />
<span>{{getAge(YearFirstChild, MonthFirstChild)}}</span>
</div>
JS(控制器):
$scope.getAge = function(year,month) {
var dateOfBirth = new Date(year, month),
now = new Date();
return now.getFullYear() - dateOfBirth.getFullYear();
};
答案 1 :(得分:0)
以下是我要做的事情:
我会使用ng-repeat
来迭代一群孩子。
父范围:
app.controller('wrapperController', ['$scope', function(scope){
scope.children = [{
name: 'John'
}
,{
name: 'Bill'
}
,{
name: 'Bob'
}];
}]);
现在我要走出困境,猜测在你真正的应用程序中,你有一些儿童的动态数据源,但我们假设它是硬编码的。
我们可以做的是将整个模板包装为html,假设以下内容位于文件child.html
中:
<count-date date-container="child">Date of birth of child:
month:<input type = "text" ng-model='dateContainer.month' required maxlength="2">
year: <input type = "text" ng-model='dateContainer.year' maxlength="4">
<span>{{child.age}}</span>
<br>
</count-date>
让我们说我们有以下两个指令:
angular.module('demo').directive('child', [function(){
return {
restrict:'E',
templateUrl: './child.html'
}
}]);
angular.module('demo').directive('countDate', [function () {
return {
restrict: 'E',
scope: {
dateContainer: '='
},
link: function (scope, element, attrs) {
scope.$watch('dateContainer.month', function(newVal, oldVal){
if(newVal && scope.dateContainer.year){
scope.dateContainer.age = Math.round((new Date() - new Date(JSON.parse(scope.dateContainer.year), JSON.parse(newVal)))/32140800000);
}
});
scope.$watch('dateContainer.year', function(newVal, oldVal){
if(newVal && scope.dateContainer.month){
scope.dateContainer.age = Math.round((new Date() - new Date(JSON.parse(newVal), JSON.parse(scope.dateContainer.month)))/32140800000);
}
});
}
}
}]);
http://plnkr.co/edit/3tnQEnnm7DQbbn0yIEbe?p=preview
这将起作用并做你想要的(我相信)。让我们谈谈它的工作原理和原因:
1)我们存储了所有孩子的数组。这允许我们使用ng-repeat
以可重复的方式迭代它们
2)我们将每个孩子传递给count-date指令中隔离范围的双向绑定。这意味着该指令将创建自己的范围,该范围不会从任何父范围继承。这是为了便于重用指令。但是,通过使用=
将双向绑定传递到范围声明中,我们将绑定到父(控制器)范围中的变量。因此,当我们修改dateContainer
count-date
时,它最初绑定的变量(在我们的例子中为child
)也会被修改。同样,如果其中一个父母修改了child
,这也会影响dateContainer
。由于ng-repeat
也绑定到它通过引用迭代的对象,因此任何更改都将一直传播到堆栈中。
3)在ng-model
和child.year
而不是child.month
或month
上设置year
,我们会确保将字段添加到现有字段对象,因此将在所有范围内可用。如果我们将ng-model
绑定到year
,我们只会在最里面的隔离范围内实例化该变量,并且我们的父母都不会收到这些新数据。
4)我们$watch
我们想要的孩子的属性。这意味着只要两个属性(dataContainer.month
或dataContainer.year
)发生变化,它们就会运行提供的回调(计算年龄),然后触发$digest
次迭代,强制重新呈现{ {child.age}}