如何将范围数据传递给没有属性的指令

时间:2013-07-24 13:47:16

标签: angularjs angularjs-directive

我有一个带隔离范围的指令。我可以将父属性传递给它(下面的'ts')。但有没有办法将父作用域数据传递给隔离范围而不使用属性?

换句话说,我想让我的指令定义访问父作用域的值(ts),而不是在html中编写的属性中发送它。 (我读到使用$ parent是不赞成的。)

原因:使用属性有效,但它看起来像一个kludge。我正在尝试编写一个组件,用户不必为我添加属性(在本例中为“ts ='ts'”),以使我的组件工作。

小提琴:http://jsfiddle.net/rrosen326/WWYuD/

<div  ng-app="testapp">
    <div ng-controller="Ctrl">
         <h1>Test of Directive</h1>

        <button ng-click="setData_ts()">Get Data</button>
        <chart-dir num='1' ts='ts'></chart-dir>
        <chart-dir num='2' ts='ts'></chart-dir>
    </div>
</div>

var app = angular.module('testapp', [])
    .controller('Ctrl', Ctrl);

function Ctrl($scope) {
    $scope.ts = -1; // timestamp 

    $scope.setData_ts = function () {
        $scope.ts = new Date().getTime();
    };

}

app.directive('chartDir', function () {
    return {
        restrict: 'EA',
        scope: {
            ts: '=',
            num: '@'
        },
        replace: true,
        template: '<div><h3>Chart {{num}}</h3><p>Time Stamp: {{ts}}</p></div>',
        link: function (scope, element, attrs) {

            scope.$watch('ts', function (newValue, oldValue) {
                // Data received - update charts
                console.log("DATA RECEIVED", newValue);
            });


        }
    };
});

2 个答案:

答案 0 :(得分:3)

  

使用属性有效,但它看起来像一个kludge。我正在尝试编写一个组件,用户不必为我添加属性(在本例中为“ts ='ts'”),以使我的组件工作。

它不是一个kludge。属性使您的指令可以重复使用可能选择使用不同$ scope属性名称的不同控制器:

<div ng-controller="Ctrl1">
   <chart-dir num='1' ts='ts1'></chart-dir>
</div>
<div ng-controller="Ctrl2">
   <chart-dir num='2' ts='ts2'></chart-dir>
</div>

换句话说,指令通常不应硬编码/假设$ scope属性名称。

指令的用户必须添加属性以指定指令执行其工作所需的数据。

答案 1 :(得分:2)

您是否考虑过使用$ broadcast事件在控制器之间进行通信(每个指令中的控制器都是主Ctrl()控制器的子控件)

我分叉你的小提琴,以告诉你我将如何做到这一点:http://jsfiddle.net/DotDotDot/YQ2Tq/1/

在HTML方面,我修改了一下你的代码,我删除了'ts'属性并修改了ng-click中的被调用函数:

<button ng-click="broadcast_ts()">Get Data</button>
    <chart-dir num='1'></chart-dir>
    <chart-dir num='2'></chart-dir>
在JS方面,我定义了broadcast_ts函数,它广播一个事件(我称之为“hello”,但你可以定义任何名称)并发送数据(我没有发送任何有用的数据,但你可以为示例将新的'ts'值发送到其中):

$scope.broadcast_ts=function()
   {
       $scope.$broadcast('hello',{"values":'I was broadcasted'})   
   }

然后,在指令中,我定义了一个$ on方法,以捕获广播事件:

scope.$on('hello', function(event, args){
                scope.ts=new Date().getTime();
                console.log("DATA RECEIVED", args.values);
            })

这个方法重新计算新的ts(你可以在小提琴中看到时间戳有微小的差别)但是你可以完全使用另一个值,或者在广播参数中传递的任何对象