如何在嵌套指令之间共享变量

How to share variable between nested directives?

本文关键字:之间 共享变量 指令 嵌套      更新时间:2023-09-26

当一个指令(称之为el2)嵌套在另一个指令(称为el1)中时,我无法访问el1中"本地声明"的变量(例如el2 ng-repeatng-init等产生的变量)。

这把小提琴说明了这个问题。代码如下:

var myApp = angular.module('myApp',[]);
// define blue `el1` element which contains an `el2` child:
myApp.directive('el1', function() { 
    return {
        restrict: 'E',
        link: function($scope) {
        },
        replace: true,
        template: '<div ng-init="value1 = 1;">' +
            'value1: {{ value1 }}' +
            ' <el2></el2>' +
            '</div>',
        scope: {
        }
    };
});
// define green `el2` element:
myApp.directive('el2', function() {
    return {
        restrict: 'E',
        link: function($scope) {
        },
        replace: true,
        template: '<span ng-init="value2 = 2;">' +
            'value1: {{ value1 || "UNDEFINED" }} value2: {{ value2 }}</span>',
        scope: {
            value1: '='
        }
    };
});

如何访问el2指令中的value1?有什么方法不涉及通过link函数或controller显式修改范围?

再说一遍:问题是在两个嵌套指令之间共享一个变量。

解决方案很简单,需要两个半步骤:

  1. 将共享变量的名称作为属性传递给内部(例如 my-var="value1"
  2. 将该属性添加到scope设置的内部指令中(例如 scope: { myVar: '=' }
    • 确保您使用dash-delimiting大小写作为属性名称(例如 my-var而不是myVar.

在此处更新了 JSFiddle。

现在,内部指令可以将外部指令的值 x.val 作为myValue1 。正如预期的那样,绑定是双向的。

法典:

var myApp = angular.module('myApp',[]);
var x = {
    val: 1
};
// define blue `el1` element which contains an `el2` child:
myApp.directive('el1', function() { 
    return {
        restrict: 'E',
        replace: true,
        controller: function($scope) {
            $scope.x = x;
        },
        template: '<div>' +
            'x.val: {{ x.val }}' +
            ' <el2 my-value1="x.val"></el2>' +
            '</div>'
    };
});
// define green `el2` element:
myApp.directive('el2', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<span ng-init="value2 = 2;">' +
            'myValue1: {{ myValue1 || "UNDEFINED" }} ' +
            '<button ng-click="myValue1 = myValue1+1;">+</button>' +
            'value2: {{ value2 }}' +
            '</span>',
        scope: {
            myValue1: '='
        }
    };
});

感谢Fabio F.指出变量名称可以通过属性简单地传输。