代码之家  ›  专栏  ›  技术社区  ›  Martin

用等效代码替换ng include

  •  0
  • Martin  · 技术社区  · 9 年前

    当我用各种HTML部分组成视图时,我更喜欢声明性的方法 ng-include 标记中的指令。

    然而,我需要动态填充项目的幻灯片放映/转盘的第三方小部件不能很好地处理 ng-repeat ng包括 (第三方小部件将在初始化小部件时接受DOM中存在的一组子节点,或者通过调用 addItem 功能)。

    <!-- this will not work properly, the items collection changes dynamically -->
    <div id="slideShowHost">
        <div class="slideShowItem"
            ng-repeat="item in controller.items"
            ng-include="'templates/slideShowItem.html'">
        </div>
    </div>
    

    因此,我将更换 幻灯片放映主机 满足于我的控制器中的等效代码。我使用 RequireJS 加载的内容 模板/slideShowItem.html 作为一个字符串,并且 jQuery 为我的所有项目创建相应的节点。但这还不够,因为我在 幻灯片显示项目 模板需要活起来。

    // I'm using typescript here, but answers may as well use untyped javascript
    var slideShowHost = $("#slideShowHost").acmeSlideShow();
    require(["slideShowItemTemplate-html"], (itemTemplate: string) =>
    {
        for (var i = 0; i < this.items.length; i++)
        {
            let initializedItem = this.initAngularDependentItem(this.items[i], itemTemplate);
            slideShowHost.addAcmeSlideShowItem( initializedItem );
        }
    });
    
    ...
    
    private initAngularDependentItem(itemModel: any, template: string): any
    {
        let itemView = $(template);
        // we have to create a scope here containing the itemModel
        // and we need to init the angular directives inside itemView
        return itemView;
    }
    

    哪种代码可以正确可靠地替代任何 ng包括 其中包含的部分可以使用 有棱角的 指令甚至嵌套 ng包括 ?

    2 回复  |  直到 9 年前
        1
  •  1
  •   jcubic    9 年前

    您需要像这样使用$compile:

    app.controller(function($scope, $compile) {
        var link = $compile(template);
        $('...').append(link($scope));
    });
    
        2
  •  0
  •   Community CDub    7 年前

    这个 answer given by jcubic 是正确的。我想补充一些细节。

    我们需要 $compile service 注入到我们的控制器中,以编译jQuery创建的HTML字符串或DOM;必须调用生成的函数将范围和模板链接在一起。 因此,我们还需要 $scope 注入。

    原始用例包含 ng-repeat 指令,它为每个项创建一个子范围,并将相应的项添加到其中(除此之外 additional properties ). 因此,我们从控制器的$scope以编程方式创建子作用域,以便将它们与链接函数一起使用。

    private static $inject = ["$scope", "$compile"];
    
    ...
    
    private initAngularDependentItem(itemModel: any, template: string): any
    {
        let itemDOM = $(template);
        let itemScope = this.$scope.$new();
        itemScope.item = itemModel;
        let link = this.$compile(itemDOM);
        let compiledAndLinked = link(itemScope);
        return compiledAndLinked;
    }
    

    关于子范围的一句话: 我的项目模板顶级节点使用 ng-controller 用于指定 项目控制器 每个项目。 此指令创建新范围。 它的分支是每个项目都创建了新的 itemScope 从我上面的代码片段中可以看出 项目控制器 将知道它自己的$scope,但是 项目控制器 的作用域是我们创建的对象的子作用域。记住这一点。当我的父控制器应该从itemScope读取属性时 项目控制器 据称是之前设定的。

    我们可以这样设置共享对象 itemScope.sharedObject = {} 因为子作用域继承了它,所以两者都是相同的。