首页 文章

如何强制角度从自定义指令渲染外部元素?

提问于
浏览
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>

元素和连接都是范围变量 . 根据我的理解,两者都在相同的范围内,执行流程从父到子开始,从子到父完成 . 在启动自定义指令之前,如何强制完成ng-repeat渲染部分?

有角度的任何替代品可以解决这种依赖吗?

3 回答

  • 0

    非常感谢您的快速回复#Royce#Lori

    我发现这个问题导致因为ng-repeat我已经用以下方式解决了它 .

    • 为列表元素创建了一个自定义指令,并在另一个指令启动之前呈现了for循环中的所有元素 . 这个修复暂时解决了这个问题,但我会尝试$ evalAsync和$ timeout :)
    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);
    });
    
  • 0

    已经有一段时间了,所以我的Angular有点生疏了 . 但如果我正确理解你的问题,那就是我遇到过几次问题 . 您似乎希望延迟处理标记的某些元素,直到其他元素完全呈现为止 . 你有几个选择:

    您可以使用超时等待页面呈现:

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

    这通常可以正常工作,但可能会导致页面不愉快地闪烁 .

    您可以使用$ evalAsync在稍后的摘要周期中渲染一些代码:

    这里有一篇关于该主题的好文章:AngularJS : $evalAsync vs $timeout . 通常,我更喜欢这个选项,因为它没有遭受同一页面闪烁问题 .

    或者,您可以寻找重构指令的方法,以便相关部分不会如此孤立 . 该选项是否有用将取决于您的应用程序的更大背景以及您希望这些部分的可重用性 .

    希望有所帮助!

  • 0

    我会为整个列表创建一个指令,也许是每个列表项的嵌套指令 . 那会让你有更多的控制权 .

相关问题