将局部变量传递给AngularJs中的指令

时间:2014-03-06 08:23:49

标签: javascript angularjs angularjs-directive angularjs-scope

我有一个控制器,为一个带有阵列的转发器提供信息:

demo.controller('MyCntl', function ($scope, $compile) {

    $scope.items = [
        { name: 'Diego' },
        { name: 'Darko' }
    ];       

    $scope.load = function (obj) {            
        $('body').append($compile("<panel data='obj'  />")($scope));
    }

});

<div ng-controller='MyCntl'>    
    <p ng-repeat='item in items'>
        <button ng-click='load(item)'>Load {{item.name}}</button>
    </p>       
</div>

如您所见,重复的项目有一个按钮来加载更多数据。单击按钮时,它会调用load(obj)函数,该函数会向页面附加一个指令:

demo.directive('panel', function () {
    return {
        restrict: 'E',
        scope: {
            data: '@'
        },
        template: '<pre>I\'m a panel called by {{data.name}}</pre>',
        controller: function ($scope, $element, $attrs) {

        }            
    }
});

问题是我无法理解如何将局部变量 obj 传递给指令。我知道我可以将变量设置为控制器的$ scope并轻松地从指令中读取它,但它会有点失败。

小提琴http://jsfiddle.net/darkoromanov/cngd9/

4 个答案:

答案 0 :(得分:2)

也许你可以创建新的范围来放置你的局部变量。
在您的情况下,您必须进行两项更改:

1)如果在指令中使用“@”,则只能传递String,如果要传递对象,请使用“=”。

scope: {  
    data: '='  
},  

2)在控制器中创建新范围

var newScope = $scope.$new();  
newScope.obj = obj;  
$('body').append($compile("<panel data='obj'  />")(newScope));  

答案 1 :(得分:1)

你可以将变量作为元素的属性传递,但它应该是当前范围的属性,所以, 我对您的代码进行了一些更改

    controller: function ($scope, $element, $attrs) {
        $scope.data = $scope.$eval($attrs.data);     
    }

这是我的JSFIDDLE看看你在寻找什么?

答案 2 :(得分:1)

在控制器中使用DOM操作并不理想,所以我建议用另一种方法来实现这一点。

我会为面板维护一个集合

$scope.panels = [];
$scope.load = function (obj) {
    $scope.panels.push(obj);
};

直接在HTML中呈现:

<panel data="{{panel.name}}" ng-repeat="panel in panels track by $index"  />

最后稍微改变指令:

demo.directive('panel', function () {
   return {
      restrict: 'E',
      scope: {
        data: '@'
      },
      template: '<pre>I\'m a panel called by {{data}}</pre>'        
  }
});

演示:http://jsfiddle.net/cngd9/1/

答案 3 :(得分:0)

我已经修好了你的小提琴。见这里

http://jsfiddle.net/BDrCr/

问题是你不能将参数传递给未绑定到范围的指令。在您的情况下obj。我还将scope属性更改为使用=

因此范围加载方法更改为

  $scope.load = function (obj) {
        var index=$scope.items.indexOf(obj);
        $('body').append($compile("<panel data='items["+ index +  "]'/>")($scope));
    }