2014-02-15 61 views
2

如果我將ui-view嵌套在transclude = true的指令中,視圖內容不會加載。沒有干預指示,它工作正常。嵌套在指令中的angular-ui視圖不會加載視圖內容

所以用含有頁:

<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中,但這似乎不是實際可見的示例指導節點,而是它的一個克隆。我猜它與編譯順序有關,因此我需要在指令中做一些巧妙的事情,但我無法在涵蓋這一點的角度api幫助中找到任何東西。

我試着添加一個後鏈接功能,並從那裏調用$ transclude但它沒有區別。

任何人都可以建議我需要添加到指令,所以這將工作。 感謝

UPDATE 從進一步調查新信息: 看來原因是這個(沒有在這一點上的解決方案,但我可以看到爲什麼它會發生)。 在angular的函數applyDirectivesToNode(angular.js line 5919)中,如果指令指定了transclude = true,那麼克隆原始指令節點以創建模板節點。即模板不是在dom中可見的原始節點。現在,當調用angular-ui-router.js行2204中的ui-view的編譯函數時,它抓取ui-view節點的父節點的副本,並將其存儲在parentEl中。但是,這裏是問題發生的地方 - 這個父節點是ui-view節點的父節點。最確切的不是在鏈接之後實際上最終在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> 
+0

請查看[這篇文章的類似問題](http://stackoverflow.com/a/20305370/547020),這也可能適用於您的情況。你可能只需要調用'$ route'的'reload()'。 –

+0

謝謝,但$ route是來自舊的角度路由ngRoute模塊。我使用的是不同的ui.router。話雖如此,這可能是相同的原則在這種情況下工作,雖然我討厭加載視圖兩次的想法 - 不是很有效!無論如何,我會看到如果方法的工作 –

+0

ui.router工程,無論'$ route'實現 - 它是一個單獨的模塊。即使在1.2版本上發生了重大變化,但使用ui.router應該沒有什麼區別(即重新加載應該可以)。無論如何,我建議在採取某種方法時解決問題,如果您使用的是ui.router,可以完全避免此問題。 –

回答