【问题标题】:Nested directives and parent scopes嵌套指令和父范围
【发布时间】:2013-09-26 11:01:28
【问题描述】:

我的问题可以在http://jsfiddle.net/miketheanimal/2CcYp/13/ 看到,这将我的问题降到最低。

我有一个控制器“main”,一个指令“outer”,它包含的指令,以及一个指令“inner”,它没有。每个指令都有一个隔离范围和一个控制器。主控制器和指令控制器设置 $scope._name = '...' 所以我可以区分它们。

var module = angular.module('miketa', []);
function main ($scope) {
    $scope._name = 'main' ;
} ;
module.directive('outer', function() {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        scope: {},
        template: '<div><div ng-transclude></div></div>',
        controller: [ '$scope', function($scope) {
            $scope._name = 'outer' ;
            document.getElementById('opn').innerHTML = $scope.$parent._name ;
        }]}});
module.directive('inner', function() {
    return {
        restrict: 'E',
        replace: true,
        scope: {},
        template: '<div></div>',
        controller: [ '$scope', function($scope) {
            $scope._name = 'inner' ;
            document.getElementById('ipn').innerHTML = $scope.$parent._name ;
        }]}});

HTML 将这些嵌套为主 -> 外部 -> 内部。指令中的控制器函数将它们的 parent 范围名称(即 *$scope.$parent._name)复制到呈现的 HTML 中(抱歉直接操作 DOM,这是最简单的显示方式名字!)。

我希望 outer 显示来自控制器的名称(即“main”),我希望 inner 显示名称from outer(即“outer”),它不是,而是显示“main”。

问题实际上表现出来,因为在实际代码中,我想在 innerouter 范围之间进行绑定,但是 inner最终绑定到 main 范围。

【问题讨论】:

  • 这很合理,我认为你的外部范围是孤立的,那么你如何继承它?
  • 是的,作用域是隔离的,所以它们在原型上不会继承,但它们确实有父作用域($scope.$parent 位),这些似乎不像我那样工作期望(内部->外部->主要)。正如我在上一段中所指出的,当我尝试在 innerouter 的范围之间进行绑定时(即在内部 范围内: { innervar: '=outervar'}).
  • 啊 ng-transclude 将 ng-scope 设置为 false !

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

事实上,这不是错误,而是期望的行为。来自docs on the $compile service

在典型设置中,小部件会创建一个隔离范围,但 嵌入不是一个孩子,而是隔离范围的兄弟。这 使小部件可以拥有私有状态,并且 嵌入要绑定到父(预隔离)范围。

另见:Why ng-transclude's scope is not a child of its directive's scope - if the directive has an isolated scope?

如果你真的需要让它工作,忘记ng-transclude,然后做:

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

function main($scope) {
    $scope._name = 'main';
};
module.directive('outer', function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {},
        template: '<div><inner></inner></div>',
        controller: ['$scope', function ($scope) {
            $scope._name = 'outer';
            document.getElementById('opn').innerHTML = $scope.$parent._name;
        }]
    }
});
module.directive('inner', function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {},
        template: '<div></div>',
        controller: ['$scope', function ($scope) {
            $scope._name = 'inner';
            document.getElementById('ipn').innerHTML = $scope.$parent._name;
        }]
    }
});

瞧!它有效。

【讨论】:

  • 我想知道 transclude 是否与它有关,我发现了一些其他类似但不完全相关的帖子。但是您的更改反而使outer毫无意义,我还不如将其滚入inner。我想要做的是有一个指令 outer 可以包装不同的内容(即包装 inner1inner2 等等) .有什么办法可以做到吗?
  • 没有任何 ng-trnasclude 隔离你必须接受的范围!如果您阅读链接线程和文档,这是AngularJSn中嵌入的逻辑
  • 哈哈祝你好运:)! Directive API 是 AngularJS 中最强大的部分,但非常难!无论如何,也许你必须接受或删除我不知道的问题
猜你喜欢
  • 2013-05-22
  • 1970-01-01
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多