Angularjs 除非是数组,否则变量手表不会开火

Angularjs 除非是数组,否则变量手表不会开火,angularjs,Angularjs,我有以下标记: <div ng-controller="DataController as vm"> <div ng-repeat="name in vm.users track by $index"> {{name}} </div> <form name="form" validation="vm.errors"> <input validator ng-model="vm.name" name="vm.name

我有以下标记:

<div ng-controller="DataController as vm">
  <div ng-repeat="name in vm.users track by $index">
    {{name}}
  </div>
  <form name="form" validation="vm.errors">
    <input validator ng-model="vm.name" name="vm.name" placeholder="name" type="text" />
    <a href="#" ng-click="vm.add(vm.name)">Add</a>
  </form>
</div>
每次添加用户时,我都会增加错误的值

我需要在指令中观察此变量,以便:

app.directive("validation", validation);

function validation() {

  var validation = {
    controller: ["$scope", controller],
    restrict: "A",
    scope: {
     validation: "="
    }
  };

  return validation;

  function controller($scope) {
    this.errors = $scope.validation;
  } 
}  

app.directive("validator", validator);

function validator() {

  var validator = {
    link: link,
    replace: false,
    require: "^validation",
    restrict: "A"
  };

  return validator;

  function link(scope, element, attributes, controller) {
    scope.$watch(function() {
     return controller.errors;
   }, function () {
     console.log(controller.errors);
  });
}
console.log显示初始值,但不显示新值:

如果我将vm.errors更改为数组,添加值,并观察其长度,则它可以正常工作:


为什么我的第一个示例不起作用?

验证
指令
控制器
中的两个示例中,您为
错误
属性指定了对
$scope.validation
值的引用

在第一个示例中,该值为数值,因此不可变-
1
-无法修改参考值。
vm.add
修改控制器实例的属性值。然后将更改传播到
validation
directive
$scope.validation
not
validation
directive controller实例
$errors
属性

在第二个示例中,值是一个数组,因此可以修改参考值。
vm.add
不会修改控制器实例的属性值。因此,
验证
指令控制器实例
错误
属性值与
数组
实例非常相同-因此它的
长度
发生了变化

使用不可变值的一种方法(如第一个示例中所示)是
$watch
控制器函数,如中所示:

其中
controller.errors
定义如下:

function controller($scope) {
  this.errors = function(){ return $scope.validation; };
}
您可以找到以下有用的答案:


如果更新代码,您可以访问已更新的属性scope.vm.errors,如果调试代码,您将看到属性controller.errors未更新(在每次摘要后调用所有手表重新评估)。如果从作用域访问属性错误,可以添加$scope.$watch并使其工作。但是,我不建议在指令中使用$scope.$watch。但这取决于你:

    var app = angular.module('app', []);

app.controller("DataController", DataController);

function DataController($scope) {

    var vm = this;
  vm.name = "Mary";
  vm.users = ["Alice", "Peter"];
  vm.errors = 1;
  vm.add = function(name) {  
      vm.errors++;
      vm.users.push(name);    
  }

}

app.directive("validation", validation);

function validation() {

  var validation = {
    controller: ["$scope", controller],
    restrict: "A",
    scope: {
      validation: "="
    }
  };

  return validation;

  function controller($scope) {
    this.errors = $scope.validation;
  } 

}  

app.directive("validator", validator);

function validator() {

  var validator = {
    link: link,
    replace: false,
    require: "^validation",
    restrict: "A"
  };

  return validator;

  function link(scope, element, attributes, controller) {
    scope.$watch(function() {
                return scope.vm.errors
    }, function () {
      console.log(scope.vm.errors);
    });
  }

}

有没有办法解决这个问题?我给出了一个数字示例,但如果我使用的数组不改变长度,那么它也不起作用。这就是我想让它发挥作用的地方你会建议什么作为替代?基本上,每个验证器将负责显示一条错误消息。我使用validation指令来定义哪个变量包含错误,而不会在所有验证器中重复它,因为它总是相同的…我使用一个指令,因为我想在我的整个应用程序中重用它。事实上,这就是我所拥有的,并且只处理长度。让我修改代码并解决一些更好的问题。你能检查一下吗密码?我在考虑在模型中创建一个名为errors的对象,它将包含每个元素的所有错误。我还将attribute元素添加到您的指令验证器中,因此您可以访问属性错误。您可以在指令或控制器中执行验证。我建议您对$scope.$watch中的元素进行所有验证,并为每个指令创建一个特殊的控制器,但这取决于您自己
function controller($scope) {
  this.errors = function(){ return $scope.validation; };
}
    var app = angular.module('app', []);

app.controller("DataController", DataController);

function DataController($scope) {

    var vm = this;
  vm.name = "Mary";
  vm.users = ["Alice", "Peter"];
  vm.errors = 1;
  vm.add = function(name) {  
      vm.errors++;
      vm.users.push(name);    
  }

}

app.directive("validation", validation);

function validation() {

  var validation = {
    controller: ["$scope", controller],
    restrict: "A",
    scope: {
      validation: "="
    }
  };

  return validation;

  function controller($scope) {
    this.errors = $scope.validation;
  } 

}  

app.directive("validator", validator);

function validator() {

  var validator = {
    link: link,
    replace: false,
    require: "^validation",
    restrict: "A"
  };

  return validator;

  function link(scope, element, attributes, controller) {
    scope.$watch(function() {
                return scope.vm.errors
    }, function () {
      console.log(scope.vm.errors);
    });
  }

}