我有一个标签控件,可以根据所选标签显示或隐藏控件中的内容。
这很好用,但是选项卡窗格的内容开始与范围奇怪地表现。在转换内容中引用范围似乎不再引用已定义的控制器范围。
这可以通过任何已经转换内容的指令来看出。鉴于具体的控制器:
app.controller("MainCtrl", function ($scope) {
$scope.getTestText = function () {
alert($scope.testText);
alert(this.testText);
}
});
在以下标记中使用:
<h1>Outside Tab</h1>
<div>
<input type="text" ng-model="testText" />
<button ng-click="testText = 'outside'">Set Test Text</button>
<button ng-click="getTestText()">Get Test Text</button>
{{testText}}
</div>
<simple-directive>
<h1>Inside Directive</h1>
<div>
<input type="text" ng-model="testText" />
<button ng-click="testText = 'inside'">Set Test Text</button>
<button ng-click="getTestText()">Get Test Text</button>
{{testText}}
</div>
</simple-directive>
请参阅this plunker。
如果单击顶部的“设置测试文本”按钮,然后单击“获取测试文本”按钮,则两个警报显示相同的内容(“外部”)。如果单击第二个“设置测试文本”按钮然后“获取测试文本”,则会有不同的结果:虽然“this”具有预期的“inside”值,但范围上的值仍然是“在外部”。
一种解决方法是在已转换内容中定义控制器,如下所示:
<simple-directive>
<h1>Inside Directive</h1>
<div ng-controller="MainCtrl">
<input type="text" ng-model="testText" />
<button ng-click="testText = 'inside'">Set Test Text</button>
<button ng-click="getTestText()">Get Test Text</button>
{{testText}}
</div>
</simple-directive>
但如果可能,我宁愿避免这种情况。
所以我的问题是:有没有更好的方法来做到这一点,不会改变范围?这只是预期的行为吗?
答案 0 :(得分:2)
ngTransclude
创建一个子(非隔离)范围:
$ transclude函数默认创建一个新的子范围source code:
transcludedScope = scope.$new();
为什么不使用原语?看到类似的答案...
演示插件:http://plnkr.co/edit/LuU6ard1JYsYCOvlP5iY?p=preview
app.controller("MainCtrl", function ($scope) {
$scope.test = {};
$scope.getTestText = function () {
alert($scope.test.text);
alert(this.test.text);
}
});
<强>模板:强>
<input type="text" ng-model="test.text" />
<button ng-click="test.text = 'inside'">Set Test Text</button>
<button ng-click="getTestText()">Get Test Text</button>
{{test.text}}
app.directive('simpleDirective', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {},
link: function(scope,elm,attrs,ctrl,$transclude){
$transclude(scope.$parent, function(clone){
elm.after(clone);
})
}
};
})