我是angular的controllerAs语法的新手,只是试图了解它如何与指令一起工作。我创建了一个用于密码验证的指令。我想根据条件将某些标志设为true,这些标志将在父模板中用于显示错误消息。我不知道该如何实现!

JSFiddle

查看

<div ng-app="myapp">
    <fieldset ng-controller="PersonCtrl as person">
        <input name="emailID" type="text" ng-model="person.first" >
        <input name="pass" type="password" ng-model="person.pass" password-validator>
        <p ng-show="person.showMsg">Password validation message here.</p>
    </fieldset>
</div>

指令
myapp.directive('passwordValidator',function() {
        return {
        controller : PasswordCtrl,
      controllerAs : 'dvm',
      bindToController : true,
      require : ['ngModel','passwordValidator'],
      link : function(scope,ele,attrs,ctrls) {
        var person = ctrls[1];
        var ngModelCtrl = ctrls[0];

        scope.$watch(function() {
                    return ngModelCtrl.$modelValue;
        },function(newVal) {
          if(newVal!='') {
            person.showMsg = true;
          } else {
            person.showMsg = false;
          }
          console.log(person.showMsg);
        });
      }
    }

    function PasswordCtrl() {

    }
});


// Why this below is also working, can anyone explain what's going behind!!
scope.$watch('person.pass',function(newVal) {
    console.log("Watch fires");
});

这只是出于学习目的,因此请解释controllerAsbindToController的工作原理!

最佳答案

我知道这不是您问题的一部分,我会解决的,但是使用指令“ng-controller”是一种反模式。如果有兴趣,为什么我可以在另一篇文章中进行解释,但总之,它使代码难以遵循。

现在,深入探讨您的问题。

通过阅读bindToController的Angular文档,您会发现,如果您还没有创建隔离的作用域,即scope: truescope: {},则不会执行任何操作。

我个人以前从未使用过它,而且似乎没有什么用处。

本质上,使用ng-controller就是使用该 Controller 对象将属性添加到当前作用域。

所以:

<fieldset ng-controller="PersonCtrl as person">

有效地说(以人为的方式):
$scope.person = new PersonCtrl();

您的指令passwordValidator在其中使用controllerAs语法,基本上是在做:
$scope.dvm= new PasswordCtrl();

在这种情况下,您实际上拥有一个范围对象,如下所示:
$scope = {
    person = new PersonCtrl(),
    dvm: new PasswordCtrl()
}

您的person Controller 和dvm Controller 是同级对象。
passwordValidator指令中,您需要其 Controller 中的dvm对象。使用那个dvm对象,您设置的person.showMsg与执行相同:
$scope.dvm.person.showMsg = <value>
dvm对象无法访问$ scope上的 sibling person对象。因此,您需要使用$ scope本身来访问person对象。您需要执行以下操作:
$scope.person.showMsg = <value>

尽管这假定person存在于范围内,但这是一个危险的假设。

10-05 20:38
查看更多