0

编辑:见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)。但是它对它没有任何作用(输入值不会更改为新的当前项)。在 Chrome 的 Batarang 中,我可以看到 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:click 值从更改show(item)currentItem = item

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

4

1 回答 1

3

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

现在,很难从您的问题中推断出在指令中使用 BaseController 是否是有意的(在问题中指令具有 EditorController)但假设这是偶然的,并且您希望将 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 ) 很有用,因为它允许可视化范围及其内容。

于 2012-08-19T15:40:01.413 回答