更新模型angularJS



我正在努力了解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);                                       
            });
        }
    };
});

我需要帮助重写指令。

如果你只想计算年龄,那么写指令有点过头了——你可以简单地写一个计算年龄的scope方法,比如:

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();
};

以下是我要做的:

我会使用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时,它最初绑定的变量(在我们的情况下为child)也会被修改。类似地,如果父母中的一方修改了child,这也会影响dateContainer。由于ng-repeat还通过引用绑定到它正在迭代的对象,因此任何更改都将一直传播到堆栈中。

3) 通过在child.yearchild.month上设置ng-model,而不是monthyear,我们确保将字段添加到现有对象中,并且因此在所有作用域中都可用。如果我们将ng-model绑定到year,我们将只在最内部的隔离范围内实例化该变量,并且我们的父母都不会收到这些新数据。

4) 我们$watch我们想要的孩子的属性。这意味着,每当两个属性(dataContainer.monthdataContainer.year)发生变化时,它们都会运行所提供的回调(计算年龄),然后触发$digest迭代,强制重新发布{{child.age}}

最新更新