AngularJS:“Controller as”语法和指​​令

时间:2014-10-19 15:51:17

标签: angularjs angularjs-directive angularjs-scope

在重构我的AngularJS代码以使用"控制器作为"后,我无法获得我的一个指令。句法。

旧工作代码(Fiddle):

<div ng-app='MyModule'>
    <div ng-controller='DefaultCtrl'>
        <input auto-complete ui-items="names" ng-model="selected"/>
        selected = {{selected}}
    </div>        
</div>

JS:

function DefaultCtrl($scope) {
    $scope.names = ["john", "bill", "charlie"];
}

angular.module('MyModule', []).directive('autoComplete', function($timeout) {
    return function(scope, iElement, iAttrs) {
            iElement.autocomplete({
                source: scope[iAttrs.uiItems],
                select: function() {
                    $timeout(function() {
                      iElement.trigger('input');
                    }, 0);
                }
            });
    };
});

这是我的非工作(自动填充建议没有出现)版本,&#34;控制器为&#34; (Fiddle):

<div ng-app='MyModule'>
    <div ng-controller='DefaultCtrl as ctrl'>
        <input auto-complete ui-items="ctrl.names" ng-model="ctrl.selected"/>
        selected = {{ctrl.selected}}
    </div>
</div>

JS:

function DefaultCtrl() {
    this.names = ["john", "bill", "charlie"];
}

angular.module('MyModule', []).directive('autoComplete', function($timeout) {
    return function(scope, iElement, iAttrs) {
            iElement.autocomplete({
                source: scope[iAttrs.uiItems],
                select: function() {
                    $timeout(function() {
                      iElement.trigger('input');
                    }, 0);
                }
            });
    };
});

3 个答案:

答案 0 :(得分:4)

问题似乎与这一行有关:

source: scope[iAttrs.uiItems],

变为:

source: scope['ctrl.names'],

我知道为什么如果与对象表示法一起使用会出现问题。


修复是为了避免这样:

source: scope.ctrl[iAttrs.uiItems], // "controller as" lets us have scope namespaces

并更改属性名称:

ui-items="names"

在此处查看整个内容:http://jsfiddle.net/cnve0jbh/2/

答案 1 :(得分:1)

正如@Shomz已经指出的那样,问题是你如何尝试访问ctrl.names。您通常不希望像这样访问范围。两种选择:

  • 使用隔离范围:

    .directive('autoComplete', function($timeout) {
      return {
        scope: {
               items: '=uiItems'
             },
        link: function(scope, iElement, iAttrs) {
                iElement.autocomplete({
                source: items,
    
  • 使用$parse服务:

    .directive('autoComplete', function($timeout, $parse) {
      return function(scope, iElement, iAttrs) {
                iElement.autocomplete({
                  source: $parse(iAttrs.uiItems)(scope),
    

答案 2 :(得分:1)

'Controller As'语法只是用于定义视图模型的超范围方法的语法糖。 它只是在$ scope对象本身中创建一个属性。如果你执行ng-controller =“MainCtrl as main”,它只会在$ scope对象中创建一个属性main,它与Controller函数对象相同。

所以在链接函数的范围对象中,它可以作为$ scope.main

访问

如上所述,您可以使用$ parse服务,也可以使用$ eval服务(内部使用$ parse) -

iElement.autocomplete({                 来源:范围。$ eval(iAttrs.uiItems),