将 ng-include 替换为等效代码
Replace ng-include with code equivalent
当用各种 HTML 部分组成我的视图时,我更喜欢在我的标记中放置 ng-include
指令的声明式方法。
但是,我需要动态填充项目的幻灯片放映/旋转木马的第三方小部件不能很好地适应 ng-repeat
和 ng-include
的动态 DOM 变化(第三方小部件将在小部件初始化时接受一组子节点出现在 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>
因此,我将用控制器中的等效代码替换 slideShowHost 内容。我使用 RequireJS to load the content of templates/slideShowItem.html as one string, and jQuery 为我的所有项目创建相应的节点。但这还不够,因为我在需要激活的 slideShowItem 模板中使用了 angular 指令。
// 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-include
,其中包含的部分可能使用任何 angular 指令甚至嵌套 ng-包含?
您需要像这样使用 $compile:
app.controller(function($scope, $compile) {
var link = $compile(template);
$('...').append(link($scope));
});
是正确的。我想补充一些细节。
我们需要将 $compile
service 注入我们的控制器,以编译 HTML 字符串或 jQuery 创建的 DOM;结果函数必须一起调用到 link 作用域和模板。
因此我们还需要注入 $scope
。
原始用例包含一个 ng-repeat
指令,它为每个项目创建一个子作用域并将相应的项目添加到其中(additional properties 除外)。因此,我们以编程方式从控制器的 $scope 创建子作用域,以使用具有 link 函数的子作用域。
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;
}
关于子作用域的一句话:
我的项目模板 top-level 节点使用 ng-controller attribute-directive 为每个项目分配一个 itemController。 此指令创建新范围。
其后果是,从我上面的代码片段 itemScope
中新创建的每个项目实际上与 itemController 知道为自己的 $scope 的对象不同,但是itemController 的范围是我们创建的对象的 child-scope。记住这一点。当我的父控制器应该从 itemController 据称之前设置的 itemScope 读取属性时,我被绊倒了。
我们可以像这样设置一个共享对象itemScope.sharedObject = {}
,因为子作用域继承了它,所以两者都是一样的。
当用各种 HTML 部分组成我的视图时,我更喜欢在我的标记中放置 ng-include
指令的声明式方法。
但是,我需要动态填充项目的幻灯片放映/旋转木马的第三方小部件不能很好地适应 ng-repeat
和 ng-include
的动态 DOM 变化(第三方小部件将在小部件初始化时接受一组子节点出现在 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>
因此,我将用控制器中的等效代码替换 slideShowHost 内容。我使用 RequireJS to load the content of templates/slideShowItem.html as one string, and jQuery 为我的所有项目创建相应的节点。但这还不够,因为我在需要激活的 slideShowItem 模板中使用了 angular 指令。
// 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-include
,其中包含的部分可能使用任何 angular 指令甚至嵌套 ng-包含?
您需要像这样使用 $compile:
app.controller(function($scope, $compile) {
var link = $compile(template);
$('...').append(link($scope));
});
我们需要将 $compile
service 注入我们的控制器,以编译 HTML 字符串或 jQuery 创建的 DOM;结果函数必须一起调用到 link 作用域和模板。
因此我们还需要注入 $scope
。
原始用例包含一个 ng-repeat
指令,它为每个项目创建一个子作用域并将相应的项目添加到其中(additional properties 除外)。因此,我们以编程方式从控制器的 $scope 创建子作用域,以使用具有 link 函数的子作用域。
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;
}
关于子作用域的一句话:
我的项目模板 top-level 节点使用 ng-controller attribute-directive 为每个项目分配一个 itemController。 此指令创建新范围。
其后果是,从我上面的代码片段 itemScope
中新创建的每个项目实际上与 itemController 知道为自己的 $scope 的对象不同,但是itemController 的范围是我们创建的对象的 child-scope。记住这一点。当我的父控制器应该从 itemController 据称之前设置的 itemScope 读取属性时,我被绊倒了。
我们可以像这样设置一个共享对象itemScope.sharedObject = {}
,因为子作用域继承了它,所以两者都是一样的。