从指令更改控制器的属性

时间:2012-08-18 20:00:49

标签: angularjs

编辑:见jsfiddle

我有一个项目列表,我通过指令显示为文本(这里简化了所有内容,它比文本更复杂,但原则上是相同的)。像这样:

<body ng:controller="BaseController">
    ...
    <div ng:controller="Controller">
        <itemdir ng:repeat="item in items" item="item"></item>
    </div>
    ...
    <input ng:model="currentItem" />
</body>

当我点击它时,它应该在输入中显示所点击项目的内容。

items数组以及currentItem属于BaseController范围。

该指令使用ng:click生成一个模板(见下文),它应该改变BaseController范围的属性(称为currentItem)。但它不会对它做任何事情(输入值不会更改为新的当前项目)。在Batarang for Chrome中,我可以看到currentItem属性在指令范围内是可见的,但在BaseController中没有。

module.directive 'itemdir', () ->
    restrict: 'E'
    replace: true
    template: '<div ng:click="show(item)"></div>'
    controller: 'EditorController'
    scope: 
        item: '=item'
    link: ($scope, $element, $attrs) ->
        update = -> 
                    $element.html($scope.item)

        $scope.$watch('item', update)

为了更改属性,我尝试了一个方法show(item),它在BaseController的范围内定义,它只将item参数赋给$ scope.currentItem。

即使我更改了ng:点击show(item)currentItem = item

的值,它也无效

我知道这是一个范围问题,但似乎我仍然没有掌握它的所有细节。

1 个答案:

答案 0 :(得分:3)

因此,查看提供的jsFiddle,我们可以看到BaseController正在顶部div中的指令中使用。这引入了一个微妙的问题,因为可以从顶部按钮和指令生成的HTML调用show(item)方法,但是这些方法在不同的控制器上调用并写入不同的范围。 / p>

现在,很难从你的问题中推断出在指令中是否有意使用BaseController(在指令中有编辑器控制器的问题)但是假设这是偶然的并且你想保留BaseController用于div并且仍然从指令调用它上面的方法在创建隔离范围时需要特别小心(因为名称暗示那些实际上是隔离的,因此不从父范围继承)。基本上,您需要确保show方法在隔离范围内可用,并指向父范围中的正确方法。

举个例子,你会像这样定义你的指令(请注意show : '&ngClick'):

module.directive('itemdir', function () {
  return {
    restrict:'E',
    replace:true,
    template:'<div ng:click="show(item)" class="clickable"></div>',
    scope : {item : '=', show : '&ngClick'},
    link:function ($scope, $element, $attrs) {
      $element.html($scope.item)
    }
  }
});

这是工作的jsFiddle:http://jsfiddle.net/pkozlowski_opensource/M9B93/

将来您可能会发现Chrome的AngularJS Batarang扩展程序(http://blog.angularjs.org/2012/07/introducing-angularjs-batarang.html)非常有用,因为它可以显示范围及其内容。