2014-07-15 80 views
0

我需要angularjs一個小的幫助, 請對這個 代碼(Chrome瀏覽器)來看看:如何強制角度從自定義指令渲染外部元素?

http://jsfiddle.net/Aravind00kumar/CrJn3/

<div ng-controller="mainCtrl"> 
    <ul id="names"> 
     <li ng-repeat="item in Items track by $index">{{item.name}} </li> 
    </ul> 

    <ak-test items="Items"> 

    </ak-test> 
</br> 
    <div id="result"> 

    </div> 
</div> 


    var app = angular.module("app",[]); 
    app.controller("mainCtrl",["$scope",function($scope){ 
     $scope.Items = [ 
      {name:"Aravind",company:"foo"}, 
      {name:"Andy",company:"ts"}, 
      {name:"Lori",company:"ts"}, 
      {name:"Royce",company:"ts"}, 
     ]; 
     $scope.Title = "Main"; 

    }]); 

app.directive("akTest",["$compile",function($compile){ 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: { 
      items: "=" 
     }, 
     link: function (scope, element, attrs) { 
//   var e =$compile('<li ng-repeat="item in Items track by $index">{{item.name}} </li>')(scope); 
//   $("#names").append(e); 

      var lilength = $("#names li").length; 
      var html ='<div> from angular ak-test directive: '+lilength+'</div>'; 
      element.replaceWith(html); 
     } 
    }; 
}]); 
     $(function(){ 
      $("#result").html('from jquery: '+$("#names li").length); 
     }); 

我創建了一個自定義的指令,並試圖從訪問一個元素在ng-repeat裏面查看我的自定義指令 問題是,在指令中它說ng-repeat還沒有呈現。 這是問題所在 我有兩個元素

<svg> 
<g> 
List of elements 
</g> 
<g> 

Based on the above rendered elements I have to draw a line between elements like a connection. I have to wait till the above elements to get render then only I can read the x,y positions and can draw a line. 
</g> 
</svg> 

兩個元件和連接是範圍變量。根據我的理解,兩者都在相同的範圍內,執行流程從父母到孩子,從孩子到父母完成。在啓動自定義指令之前,我如何強制上面的重複渲染部分完成?

有沒有其他角度可用來解決這種依賴關係?

回答

0

這已經有一段時間了,所以我的Angular變得有點生疏。但是如果我正確理解你的問題,那是我碰到過的幾次。看起來你想延遲處理標記中的某些元素,直到其他元素完全呈現。你有這樣做的幾個選項:

您可以使用超時等待頁面渲染:

$timeout(function() { 
    // do some work here after page loads 
}, 0); 

這通常工作正常,但可能會導致你的頁面令人不快的閃爍。

你可以有你的一些代碼的呈現使用$ evalAsync以後的消化週期:

有關於該主題有好的職位:AngularJS : $evalAsync vs $timeout。通常,我更喜歡這個選項,因爲它不會遇到相同的頁面閃爍問題。

或者,您可以尋找方法來重構您的指令,以便相關部分不會如此孤立。這個選項是否會有所幫助,取決於應用程序的大環境以及您希望這些組件的可重用性。

希望有幫助!

+0

謝謝勞斯萊斯!+1 – Aravind00Kumar

0

我會爲整個列表創建一個指令,也可能是每個列表項的嵌套指令。這會給你更多的控制權,我會想。

+0

謝謝洛瑞! +1 – Aravind00Kumar

0

非常感謝您的快速反應#Royce#Lori

我發現這個問題,因爲造成NG-重複我在下面的方式解決它..

  1. 創建自定義指令列出元素並在其他指令開始之前將所有元素呈現在for循環中。此修復程序暫時解決了這個問題,但我會盡力的$ evalAsync和$超時太:)

    var app = angular.module("app",[]); 
    app.controller("mainCtrl",["$scope",function($scope){ 
    $scope.Items = [ 
        {name:"Aravind",company:"foo"}, 
        {name:"Andy",company:"ts"}, 
        {name:"Lori",company:"ts"}, 
        {name:"Royce",company:"ts"}, 
    ]; 
    $scope.Title = "Main"; 
    
    }]); 
    
    app.directive("akList",["$compile",function($compile){ 
    return { 
    restrict: 'A', 
    replace : false, 
    link: function (scope, element, attrs) { 
        var _renderListItems = function(){ 
        $(element).empty(); 
        for(var i=0;i<scope.Items.length; i++) 
         { 
         var li ='<li> '+ scope.Items[i].name +' </li>'; 
         element.append(li); 
         } 
        }; 
        _renderListItems(scope); 
        scope.$watch('Items.length', function (o, n) { 
         _renderListItems(scope); 
        }, true); 
    }};}]); 
    
    app.directive("akTest",["$compile",function($compile){ 
    return { 
    restrict: 'E', 
    replace: true, 
    scope: { 
        items: "=" 
    }, 
    link: function (scope, element, attrs) { 
        var lilength = $("#names li").length; 
        var html ='<div> from angular ak-test directive: '+lilength+'</div>'; 
        element.replaceWith(html); 
    } 
    }; 
    }]); 
    $(function(){ 
        $("#result").html('from jquery: '+$("#names li").length); 
    });