2014-10-19 103 views
4

重构我的AngularJS代码以使用“控制器为”语法后,我无法获得我的一个指令。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); 
       } 
      }); 
    }; 
}); 

这里是我的非工作(自动完成建议不会出现)与 “控制器”(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); 
       } 
      }); 
    }; 
}); 
+0

你在哪里注册你的控制器角?我缺少类似“angular.module('MyModule',[]) .controller('DefaultCtrl',DefaultCtrl);” – John 2014-10-19 15:56:47

+1

@John如果是这样的话,原代码将不会工作。所以它很清楚,但OP选择不在这里展示,因为它是无关紧要的。 – Shomz 2014-10-19 16:06:52

+0

@Shomz你说得对,我很抱歉。 – John 2014-10-19 16:09:40

回答

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/

+5

或者更好的是,将uiItems声明为指令作用域元素('scope:{uiItems:'='}'),并因此传递数组本身而不是传递数组的名称。 http://jsfiddle.net/kq1z83yk/1/ – 2014-10-19 16:20:36

1

正如已经指出的那样ut by @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), 
    
1

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

所以在链接功能的范围对象,可以为$ scope.main

正如上面指出的那样,你可以使用$解析服务,也可以使用这样的eval $服务(内部使用访问$解析) -

iElement.autocomplete({source:scope。$ eval(iAttrs。uiItems),

相关问题