我已经构建了一个小模式,可以根据模型递归创建不同的子指令。我正在使用$compile
递归地构建子指令,然后将它们附加到父节点
指令构建本身似乎工作正常,但由于某种原因,嵌入式表达式或ng-bind
或插值似乎不适用于嵌套指令。
这是一个片段:
app.directive("child", function ($compile) {
function getTemplate(depth) {
if (depth % 2 == 0) {
return "<even depth='deeper'/>"
} else {
return "<odd depth='deeper'/>"
}
}
return {
scope: {
depth: "="
},
link: function linker($scope, $element) {
if ($scope.depth == 0) {
var child = angular.element("<span ng-bind='depth'/>");
child = $compile(child)($scope);
$element.append(child);
} else {
$scope.deeper = $scope.depth - 1;
var child = angular.element(getTemplate($scope.depth));
child = $compile(child)($scope);
$element.append(child);
}
}
}
})
在此测试中,指令将以递归方式向下潜行,直至depth
到达0
,然后吐出<span>
元素。
预期结果应为span元素,其值为0
。但它似乎没有评估。使用<span>{{depth}}</span>
也会导致文字html而不是评估内容
我正在尝试实现嵌套<even><odd><even>
指令的结果 删除 周围的<child>
- 指令。
这是一个完整的jsFiddle:https://jsfiddle.net/eg1e1aLz/
生成的DOM应如下所示:
<test depth="4" class="ng-isolate-scope">
<even depth="depth-1" class="ng-scope ng-isolate-scope">
<odd depth="depth-1" class="ng-scope ng-isolate-scope">
<even depth="depth-1" class="ng-scope ng-isolate-scope">
<odd depth="depth-1" class="ng-scope ng-isolate-scope"><span ng-bind="depth" class="ng-binding ng-scope">0</span></odd>
</even>
</odd>
</even>
</test>
答案 0 :(得分:3)
根据您在下面的评论和问题的更新,以下内容......
它使用模板函数getTemplate
来构建结构,并使用相同的指令:odd
和even
作为构建功能的占位符。
var app = angular.module("app", []);
app.directive("test", function($compile) {
return {
scope: {
depth: "="
},
link: function linker($scope, $element, $attrs) {
// template accessible to the child directives
$scope.getTemplate = function(depth) {
if (depth <= 0) {
return "<span ng-bind='depth'/>"; // also bindings like {{depth}} work
} else if (depth % 2 === 0) {
return "<even depth='depth-1'></even>"; // bindings like {{depth}} work
} else {
return "<odd depth='depth-1'></odd>";
}
}
var child = angular.element($scope.getTemplate($scope.depth));
$compile(child)($scope);
$element.append(child);
}
}
});
app.directive("odd", function($compile) {
return {
scope: {
depth: "="
},
link: function linker($scope, $element) {
$scope.getTemplate = $scope.$parent.getTemplate; // bring template into current scope
var child = angular.element($scope.getTemplate($scope.depth));
$compile(child)($scope);
$element.append(child);
}
}
})
app.directive("even", function($compile) {
return {
scope: {
depth: "=",
},
link: function linker($scope, $element) {
$scope.getTemplate = $scope.$parent.getTemplate; // bring template into current scope
var child = angular.element($scope.getTemplate($scope.depth));
$compile(child)($scope);
$element.append(child);
}
}
})
var controller = app.controller("controller", function($scope) {});
更新小提琴:https://jsfiddle.net/bda411fj/15/
<强>结果:强>
<test depth="4" class="ng-isolate-scope">
<even depth="depth-1" class="ng-binding ng-scope ng-isolate-scope">
<odd depth="depth-1" class="ng-binding ng-scope ng-isolate-scope">
<even depth="depth-1" class="ng-binding ng-scope ng-isolate-scope">
<odd depth="depth-1" class="ng-binding ng-scope ng-isolate-scope">
<span ng-bind="depth" class="ng-binding ng-scope">0</span>
</odd>
</even>
</odd>
</even>
</test>
答案 1 :(得分:1)
模板的已编译部分只需在child.html()
上作为子项引用
将您的代码更改为从$element.append(child.html());
到$element.append(child);
这将开始打印您要查找的深度值。还有其他你在找什么?
答案 2 :(得分:0)
你的html可能没有被清理,因为它没有编译尝试使用ngSanatize可以解决你的问题 https://docs.angularjs.org/api/ngSanitize/service/ $ sanitize 它将删除所有潜在危险的令牌和会给你一个合适的HTML。
答案 3 :(得分:0)
由于您不想使用html(),请不要使用child.html()。
使用孩子本身。
查看此处的文档
检查下面的代码段。根据您问题中的示例代码段添加
var app = angular.module("app", []);
app.directive("test", function($compile) {
return {
scope: {
depth: "="
},
link: function linker($scope, $element, $attrs) {
var child = angular.element("<child depth='depth'/>");
child = $compile(child)($scope);
$element.append(child);
}
}
});
app.directive("child", function($compile) {
function getTemplate(depth) {
return depth % 2 == 0 ? "<even depth='depth-1'/>" : "<odd depth='depth-1'/>"
}
return {
scope: {
depth: "="
},
link: function linker($scope, $element) {
if ($scope.depth == 0) {
var child = angular.element("<span ng-bind='depth'/>");
child = $compile(child)($scope);
$element.append(child);
} else {
var child = angular.element(getTemplate($scope.depth));
child = $compile(child)($scope);
$element.append(child);
}
}
}
})
app.directive("odd", function($compile) {
return {
scope: {
depth: "="
},
link: function linker($scope, $element) {
var child = angular.element("<child depth='depth'/>");
child = $compile(child)($scope);
$element.append(child);
}
}
})
app.directive("even", function($compile) {
return {
scope: {
depth: "="
},
link: function linker($scope, $element) {
var child = angular.element("<child depth='depth'/>");
child = $compile(child)($scope);
$element.append(child);
}
}
})
var controller = app.controller("controller", function($scope) {});
body {
padding: 5px 5px 5px 5px !important;
font-size: 30px;
}
test,
child,
even,
odd {
padding: 5px 5px 5px 5px;
margin: 5px 5px 5px 5px;
border: 1px solid black;
}
test {
background-color: aliceblue !important;
}
child {
background-color: beige !important;
}
even {
background-color: lightgreen !important;
}
odd {
background-color: lightcoral !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<body ng-app="app" ng-controller="controller">
<test depth="4"></test>
</body>
答案 4 :(得分:0)
你的jsfiddle非常好,唯一的问题是一点逻辑。
当你编译子指令时,你不应该仅仅附加child.html()
,因为这会附加一个没有绑定的HTML和连接到它们的观察者。相反,你应该追加整个孩子
https://jsfiddle.net/eg1e1aLz/2/
child = $compile(child)($scope);
$element.append(child);
答案 5 :(得分:0)
很抱歉,如果我错过了你想要完成的内容,但我不相信你需要使用子指令或类似的东西。您可以使用test指令并不断构建子节点,然后将范围绑定到最后一个:
angular.module("app", [])
.directive("test", function ($compile) {
return {
scope: {
depth: "="
},
link: function linker($scope, $element, $attrs) {
var element = $element;
for (var x = 0; x < $scope.depth; x++) {
var elementType = x % 2 === 0 ? 'even' : 'odd';
var subElement = angular.element(document.createElement(elementType));
element.append(subElement);
element = subElement;
}
var span = angular.element('<span ng-bind="depth" />');
element.append(span);
$compile(span)($scope);
}
}
})
小提琴:https://jsfiddle.net/ffyv0zmy/
我在你的例子中意识到你想要输出为“0”的深度,但你可以硬编码,因为我不确定它的用途。
结果HTML:
<test depth="4" class="ng-isolate-scope">
<even>
<odd>
<even>
<odd>
<span ng-bind="depth" class="ng-binding ng-scope">4</span>
</odd>
</even>
</odd>
</even>
</test>
关于这一点的好处是你不必将范围附加到偶数/奇数元素,除非你也想要。
你仍然可以将指令连接到每个奇数/偶数元素,但是你必须编译$元素而不是附加所有范围。