2016-09-29 28 views
4

我刚刚接触到了controllerAs的angular语法,并试图了解它如何与指令一起工作。我创建了一个用于密码验证的指令。我想根据条件使标记为真,并且这些标记将用于父模板中以显示错误消息。我没有得到我该如何实现这一点!

JSFiddle

VIEW

<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作品!

+0

你的要求是什么?解释或解决方案 –

+0

解决方案详细说明它的工作原理。 –

+0

在angularjs中使用指令时(或者只是使用angularjs),它对于理解摘要生命周期很重要,它基本上是对作用域模型和视图之间的变化进行脏检查。这是使我们的生活更容易的核心功能。这是我读过的关于该主题的最好的文章https://www.sitepoint.com/understanding-angulars-apply-digest/ –

回答

1

我知道这不是你的问题的一部分,我会得到它,但使用的指令“NG控制器”是一个反模式。如果如果如果有兴趣,我可以在另一篇文章中解释,但总之,它使代码更难以遵循。

现在,去问你的问题的核心。

从阅读bindToController的Angular文档可以看出,如果您还没有创建隔离范围,即scope: truescope: {},那么它不会执行任何操作。

我个人从来没有使用过它,似乎并不特别有用。

使用ng-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控制器和dvm控制器是兄弟对象。 在您的passwordValidator指令中您需要在其控制器中使用dvm对象。使用dvm对象你要为person.showMsg这是因为这样做是相同的:

$scope.dvm.person.showMsg = <value> 

dvm对象没有办法访问person对象,因为它们是兄弟姐妹,在$范围。所以你需要使用$ scope来访问person对象。你需要做的:

$scope.person.showMsg = <value> 

虽然这个假设person存在的范围,这是一个危险的假设。

1

你的例子有点凌乱,但生病试图回答你的问题。

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

这是有效的,因为您的指令使用SAME作用域和变量作为其父控制器。

this.checkDirCtrl = function() { 
    console.log($scope.dvm); 
} 

this因为您使用的是相同的范围内使新的变量controllerAs称为dvm没有创建和所有的控制器dvm变量是在父范围初始化是不确定的。

这意味着您不需要将人员控制器注入指令,因为您已经在指令范围上有控制器实例。所以只需设置你的变量'showMsg'就可以了,它就像魔术一样工作!

 if(newVal!='') { 
     scope.person.showMsg = true; 
     } else { 
     scope.person.showMsg = false; 
     } 
     console.log(scope.person.showMsg); 

我做了一个捣鼓你:JSFiddle

+0

我不想使用范围.. –

相关问题