【问题标题】:angular-ui view nested in a directive does not load view content嵌套在指令中的 angular-ui 视图不加载视图内容
【发布时间】:2014-03-15 05:57:59
【问题描述】:

如果我将 ui-view 嵌套在 transclude=true 的指令中,则不会加载视图内容。没有干预指令,它可以正常工作。

所以页面包含:

<body>
<div ng-controller="MainController">
        <div ui-view="sampleView"></div>
</div>
</body>

sampleView 内容出现。

但是如果我放了

<body>
<div ng-controller="MainController">
    <div sample-directive>
        <div ui-view="sampleView"></div>
    </div>
</div>
</body>

那么视图内容就不会出现了。

我创建了一个简单的 html 页面来演示这个问题,见下文。

据我所知,角度编译过程确实正确调用了angular-ui中ui-view指令中的updateView,并且确实构建了视图内容并将其插入到sample-directive节点下的dom中,但是这似乎不是实际可见的样本指令节点,而是它的克隆。我猜它与编译顺序有关,因此我需要在指令中做一些聪明的事情,但我在 angular api 帮助中找不到任何涵盖这一点的内容。

我尝试添加一个后链接函数并从那里调用 $transclude,但没有任何区别。

任何人都可以建议我需要在指令中添加什么,这样就可以了。 谢谢

更新 进一步调查的新信息: 原因似乎是这个(此时不是解决方案,但我可以看到它为什么会发生)。 在 Angular 的函数 applyDirectivesToNode(angular.js 第 5919 行)中,如果指令指定 transclude=true,则克隆原始指令节点以制作模板节点。即模板不是在dom中可见的原始节点。现在,当调用 angular-ui-router.js 第 2204 行中 ui-view 的 compile 函数时,它会抓取 ui-view 节点的父节点的副本,并将其存储在 parentEl 中。但是,这就是问题所在——这个父节点是 ui-view 节点的 dom 中的父节点。最肯定不是链接后实际上最终在dom中结束的父实例。稍后当 ui-view 更新初始路由更改时,它构建视图内容并将其插入到 parentEl 下(angular-ui-router.js 第 2273 行),但正如我们之前看到的,这在链接后不在可见 dom 中.它是源 html 节点,而不是通过编译和链接嵌套 ui-view 的指令创建的克隆。

我认为这可能是 ui-view 中的一个错误。

可能有一种方法可以向指令添加解决方法,以获取链接后视图实例并将其放入指令中。如果我弄清楚了,我会添加一个答案。

html 来演示问题如下:

<!DOCTYPE html>
<html lang="en" ng-app="viewInDirectiveApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>View inside a directive</title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script>

<script src="modules/angular-ui-router.js"></script>

<script>
    var viewInDirectiveApp = angular.module('viewInDirectiveApp', ['ui.router']);

    viewInDirectiveApp.config(function ($stateProvider, $urlRouterProvider) {
        $stateProvider
            .state('sampleState', {
                url: '/sampleState',
                views: {
                    sampleView: {
                        template: 'This is the view content',
                        controller: function ($scope) {
                        }
                    }
                }
            });
        $urlRouterProvider.otherwise("/sampleState");
    })
    .controller('MainController', ['$scope',
        function ($scope) {
        }])
    .directive('sampleDirective', function () {
        return {
            template: 'Start directive content <div ng-transclude></div> End directive content',
            transclude: true
        };
    });
</script>
</head>
<body>
<div ng-controller="MainController">
    Before sampleDirective
    <div sample-directive>
        Before sampleView
        <div ui-view="sampleView"></div>
        After sampleView
    </div>
    After sampleDirective
</div>
</body>
</html>

【问题讨论】:

  • 查看this post on a similar issue,这也可能适用于您的情况。您可能只需要调用$routereload()
  • 谢谢,但是 $route 来自旧的角度路由 ngRoute 模块。我正在使用不同的 ui.router。话虽如此,在这种情况下,同样的原则可能会起作用,尽管我讨厌两次加载视图的想法 - 效率不高!无论如何,我会看看这种方法是否有效
  • ui.router 工作与$route 实现无关——它是一个单独的模块。即使在 1.2 上发生了重大更改,您对 ui.router 的使用应该没有什么区别(即重新加载应该可以工作)。无论如何,我建议的是在采取某种方法时解决问题的方法,如果您使用的是 ui.router,则可以完全避免这种方法。

标签: javascript angularjs angular-ui-router


【解决方案1】:

已确认 ui-router 0.2.8 中的错误:https://github.com/angular-ui/ui-router/issues/774

在 0.2.10 中修复:https://github.com/angular-ui/ui-router/pull/858

【讨论】:

    【解决方案2】:

    非常感谢 Plunkers:http://plnkr.co/edit/TZ8hvkSbCIa0dTj0NkcG?p=preview - 似乎在 Angular-routing 中工作:http://dotjem.github.io/angular-routing/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多