AngularJS:带有引用指令和数据绑定的模板的指令

AngularJS:带有引用指令和数据绑定的模板的指令,angularjs,data-binding,angularjs-directive,Angularjs,Data Binding,Angularjs Directive,我使用的是AngularJS 1.5.3。我有一个从另一个指令中调用一个指令的用例。换句话说,指令是链接的。我希望根据内部指令的结果更新外部指令上的范围变量。我在这里创建了一个JSFIDLE:它显示了我的尝试 此处复制了相同的代码: <div ng-app="myApp" ng-controller="MyCtrl"> <span first-layer-directive first-layer-info="'fist layer text'"></spa

我使用的是AngularJS 1.5.3。我有一个从另一个指令中调用一个指令的用例。换句话说,指令是链接的。我希望根据内部指令的结果更新外部指令上的范围变量。我在这里创建了一个JSFIDLE:它显示了我的尝试

此处复制了相同的代码:

<div ng-app="myApp" ng-controller="MyCtrl">
    <span first-layer-directive first-layer-info="'fist layer text'"></span>
</div>

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope) {

});

myApp.directive('firstLayerDirective', function() {
    return {
        scope: {
            firstLayerInfo: '='
        },
        template: "<div><span>1st Layer Displayed info='{{firstLayerDisplay}}'</span></div>" +
        "<div>" +
        "<span second-layer-directive second-layer-info=\"'second layer text'\" info=\"info\">Second layer displayed info='{{secondLayerDisplay}}'</span></div>" + "<span>Info returned from 2nd layer: {{info}}</span>",
        link: function (scope, element, attrs) {
            scope.firstLayerDisplay = scope.firstLayerInfo;
            scope.info = '';
        }
    };
});

myApp.directive('secondLayerDirective', function() {
    return {
        scope: {
            secondLayerInfo: '=',
            info: '='
        },
        template: "<div><span>2nd Layer Displayed info='{{secondLayerDisplay}}'</span></div>",
        link: function (scope, element, attrs) {
            scope.secondLayerDisplay = scope.secondLayerInfo + ' plus more info';
            scope.info='info generated in 2nd layer';
        }
    };
});
相反,我希望最后一行显示以下内容: 第二层返回的信息:第二层生成的信息

如何将数据从内部指令传递回外部指令,并确保外部指令用新值更新?

更新 正如OP所指出的,最初的解决方案“有效”,但实际上并不正确。我相信这是因为内联模板与链接函数一起编译的方式。如果将链接功能更改为使用预链接,则它似乎可以工作

link: {
          pre: function (scope, element, attrs) {
            scope.firstLayerDisplay = scope.firstLayerInfo;
            scope.info = '';
            }
        }

原始答案

为了解决这个问题,您需要使用所谓的“点表示法”(参见此处的解释)

如果您更改父指令,使其看起来像下面的代码,则应修复您看到的问题

myApp.directive('firstLayerDirective', function() {
    return {
        scope: {
            firstLayerInfo: '='
        },
        template: "<div><span>1st Layer Displayed info='{{firstLayerDisplay}}'</span></div>" +
        "<div>" +
        "<span second-layer-directive second-layer-info=\"'second layer text'\" info=\"info.text\">Second layer displayed info='{{secondLayerDisplay}}'</span></div>" + "<span>Info returned from 2nd layer: {{info}}</span>",
        link: function (scope, element, attrs) {
            scope.firstLayerDisplay = scope.firstLayerInfo;
            scope.info.text = '';
        }
    };
});
myApp.directive('firstlayerddirective',function(){
返回{
范围:{
第一层信息:'='
},
模板:“第一层显示信息={{firstLayerDisplay}}”+
"" +
“第二层显示的信息=“{{secondLayerDisplay}}'”+“从第二层返回的信息:{{info}}”,
链接:函数(范围、元素、属性){
scope.firstLayerDisplay=scope.firstLayerInfo;
scope.info.text='';
}
};
});
我所做的唯一更改是将“scope.info=””更改为“scope.info.text=”,然后将“info.text”传递给html中的子指令

如果您有任何问题,请告诉我。

更新 正如OP所指出的,最初的解决方案“有效”,但实际上并不正确。我相信这是因为内联模板与链接函数一起编译的方式。如果将链接功能更改为使用预链接,则它似乎可以工作

link: {
          pre: function (scope, element, attrs) {
            scope.firstLayerDisplay = scope.firstLayerInfo;
            scope.info = '';
            }
        }

原始答案

为了解决这个问题,您需要使用所谓的“点表示法”(参见此处的解释)

如果您更改父指令,使其看起来像下面的代码,则应修复您看到的问题

myApp.directive('firstLayerDirective', function() {
    return {
        scope: {
            firstLayerInfo: '='
        },
        template: "<div><span>1st Layer Displayed info='{{firstLayerDisplay}}'</span></div>" +
        "<div>" +
        "<span second-layer-directive second-layer-info=\"'second layer text'\" info=\"info.text\">Second layer displayed info='{{secondLayerDisplay}}'</span></div>" + "<span>Info returned from 2nd layer: {{info}}</span>",
        link: function (scope, element, attrs) {
            scope.firstLayerDisplay = scope.firstLayerInfo;
            scope.info.text = '';
        }
    };
});
myApp.directive('firstlayerddirective',function(){
返回{
范围:{
第一层信息:'='
},
模板:“第一层显示信息={{firstLayerDisplay}}”+
"" +
“第二层显示的信息=“{{secondLayerDisplay}}'”+“从第二层返回的信息:{{info}}”,
链接:函数(范围、元素、属性){
scope.firstLayerDisplay=scope.firstLayerInfo;
scope.info.text='';
}
};
});
我所做的唯一更改是将“scope.info=””更改为“scope.info.text=”,然后将“info.text”传递给html中的子指令


如果您有任何问题,请告诉我。

您需要的是
ng transclude

我为你树立了一个榜样,看看

此处复制了相同的代码:

<div ng-app="myApp" ng-controller="MyCtrl">
    <span first-layer-directive first-layer-info="'fist layer text'"></span>
</div>

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope) {

});

myApp.directive('firstLayerDirective', function() {
    return {
        scope: {
            firstLayerInfo: '='
        },
        template: "<div><span>1st Layer Displayed info='{{firstLayerDisplay}}'</span></div>" +
        "<div>" +
        "<span second-layer-directive second-layer-info=\"'second layer text'\" info=\"info\">Second layer displayed info='{{secondLayerDisplay}}'</span></div>" + "<span>Info returned from 2nd layer: {{info}}</span>",
        link: function (scope, element, attrs) {
            scope.firstLayerDisplay = scope.firstLayerInfo;
            scope.info = '';
        }
    };
});

myApp.directive('secondLayerDirective', function() {
    return {
        scope: {
            secondLayerInfo: '=',
            info: '='
        },
        template: "<div><span>2nd Layer Displayed info='{{secondLayerDisplay}}'</span></div>",
        link: function (scope, element, attrs) {
            scope.secondLayerDisplay = scope.secondLayerInfo + ' plus more info';
            scope.info='info generated in 2nd layer';
        }
    };
});
var myApp=angular.module('myApp',[]);
myApp.controller('MyCtrl',函数($scope){
$scope.foo=“我是foo!”;
$scope.lines=[];
$scope.addLine=函数(){
$scope.lines.push($scope.lines.length);
}; 
});
myApp.directive('firstlayerddirective',function(){
返回{
范围:{
第一层信息:'='
},
是的,
模板:“第一层显示信息=“{{firstLayerDisplay}}”,
链接:函数(范围、元素、属性){
scope.firstLayerDisplay=scope.firstLayerInfo;
scope.info='';
}
};
});
myApp.directive('secondlayerddirective',function(){
返回{
范围:{
第二层信息:'=',
信息:'='
},
模板:“第二层显示信息={{secondLayerDisplay}}'”,
链接:函数(范围、元素、属性){
scope.secondLayerDisplay=scope.secondLayerInfo+“加上更多信息”;
scope.info='info在第二层生成';
}
};
});

加行
我是新来的。{{foo}}
第二层显示的信息=“{secondLayerDisplay}}”从第二层返回的信息:{{info}

您需要的是
ng transclude

我为你树立了一个榜样,看看

此处复制了相同的代码:

<div ng-app="myApp" ng-controller="MyCtrl">
    <span first-layer-directive first-layer-info="'fist layer text'"></span>
</div>

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope) {

});

myApp.directive('firstLayerDirective', function() {
    return {
        scope: {
            firstLayerInfo: '='
        },
        template: "<div><span>1st Layer Displayed info='{{firstLayerDisplay}}'</span></div>" +
        "<div>" +
        "<span second-layer-directive second-layer-info=\"'second layer text'\" info=\"info\">Second layer displayed info='{{secondLayerDisplay}}'</span></div>" + "<span>Info returned from 2nd layer: {{info}}</span>",
        link: function (scope, element, attrs) {
            scope.firstLayerDisplay = scope.firstLayerInfo;
            scope.info = '';
        }
    };
});

myApp.directive('secondLayerDirective', function() {
    return {
        scope: {
            secondLayerInfo: '=',
            info: '='
        },
        template: "<div><span>2nd Layer Displayed info='{{secondLayerDisplay}}'</span></div>",
        link: function (scope, element, attrs) {
            scope.secondLayerDisplay = scope.secondLayerInfo + ' plus more info';
            scope.info='info generated in 2nd layer';
        }
    };
});
var myApp=angular.module('myApp',[]);
myApp.controller('MyCtrl',函数($scope){
$scope.foo=“我是foo!”;
$scope.lines=[];
$scope.addLine=函数(){
$scope.lines.push($scope.lines.length);
}; 
});
myApp.directive('firstlayerddirective',function(){
返回{
范围:{
第一层信息:'='
},
是的,
模板:“第一层显示信息=“{{firstLayerDisplay}}”,
链接:函数(范围、元素、属性){
scope.firstLayerDisplay=scope.firstLayerInfo;
scope.info='';
}
};
});
myApp.directive('secondlayerddirective',function(){
返回{
范围:{
第二层信息:'=',
信息:'='
},
模板:“第二层显示信息={{secondLayerDisplay}}'”,
链接:函数(范围、元素、属性){
scope.secondLayerDisplay=scope.secondLayerInfo+“加上更多信息”;
scope.info='info在第二层生成';
}
};
});

加行
我是新来的。{{foo}}
第二层显示的信息=“{secondLayerDisplay}}”从第二层返回的信息:{{info}