更新模型angularJS

时间:2014-04-24 07:06:40

标签: javascript 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);                                       
            });
        }
    };
});

我需要帮助重写指令。

2 个答案:

答案 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-modelchild.year而不是child.monthmonth上设置year,我们会确保将字段添加到现有字段对象,因此将在所有范围内可用。如果我们将ng-model绑定到year,我们只会在最里面的隔离范围内实例化该变量,并且我们的父母都不会收到这些新数据。

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