繁体   English   中英

在Angular中动态包含组件

[英]Dynamically Including Components in Angular

我有一个角度应用程序,该程序具有(到目前为止)插件机制,因此我可以在运行时添加和修改菜单项。 为此,我提供了一个插件可以自行注册的服务,例如:

MenuService.addItem(
    "/main/foo",
    "bar",
    {
        title : "Bar",
        templateUrl : "foo/bar/templates/bar.html",
        controller : "BarController",
        controllerAs : "bar",
        visible : true,
        [...]
    }
);

然后我有一条指令来检索和迭代添加给定层次结构级别的项目。 在内部,这使用$ route来注册路由,并且模板可以呈现如下结构:

 <li menu-item path="/main">
     <a href="{{item.path}}">{{item.title}}</a>
     <ul ng-if="items.children.length>0">
         <li menu-item path="{{item.path}}">
         </li>
     </ul>
 </li>

这一切都非常简单,而且效果很好。 现在,我也想以类似的方式包括整个视图。 大概是这样的:

<div include-components path="/main/foo">
</div>

我想遍历在此路径中注册的项目,并复制指令所在的节点,或添加具有正确模板和控制器集的子节点。 如果只有上述一项被注册,则生成的DOM应该如下所示:

<div 
    include-components 
    path="/main/foo" 
    ng-controller="BarController" 
    ng-include="...template.html">

    [included template+controller render here]

</div>

或(带有子元素):

<div include-components path="/main/foo">
    [first registered template /w controller]
    [second registered template /w controller]
    [...]
</div>

我目前的尝试看起来像这样:

angular.module("angular-plugin").directive(
    "includeComponents",
    function(MenuService,$route,$templateCache) {
        console.log($route);
        return {
            transclude: 'element',
            scope: {
                path : "@"
            },
            link: function(scope, el, attr, ctrl,transclude) {
                var items = MenuService.get(scope.path);
                items.forEach(function(each){
                     [... what?]
                });
            }
        }
    }
});

我在该循环中尝试了很多不同的事情……但是我无法使模板显示出来,更不用说让该项目中的控制器进行初始化了。 我正在查看ngView的源代码,它应该做的事情确实非常相似...但是我无法使其正常工作。 有任何想法吗?

好的,现在我花了更多时间看ngView ...,然后找出了下面的指令。 这确实可以工作。 缺少什么吗? 之后我需要做任何清理吗?

angular.module("foobar").directive(
    "includeComponents",
    function(PluginMenuService,$route,$templateCache,$controller,$compile) {
        console.log($route);
        return {
            scope: {
                path : "@"
            },
            link: function(scope, el, attr, ctrl,transclude) {
                var items = PluginMenuService.get(scope.path);
                if(items.length > 0) {
                    items.forEach(
                        function(each) {
                            templ = $templateCache.get(each.templateUrl);
                            var child = el.append(templ);
                            var controller = $controller(each.controller, {});
                            var link = $compile(child.contents());

                            childScope = scope.$new();

                            childScope[each.controllerAs] = controller;
                            childScope["component"] = each;
                            child.data('$ngControllerController', controller);

                            link(childScope);
                        }
                    );
                }
            }
        }
    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM