Angularjs 韩元';当从ng repeat循环放入DOM时,不能编译
在工作中,我必须显示许多表,其中的数据可以动态快速地更改。为了简化这个过程,我一直在开发一个声明性表指令 通常会有一些表,其中包含与之相关联的ID,比如客户机。我正试图在Id周围放置一个链接,这样当用户单击它时,他们将获得更多详细信息或指向不同的页面。插入DOM时,Angularjs 韩元';当从ng repeat循环放入DOM时,不能编译,angularjs,Angularjs,在工作中,我必须显示许多表,其中的数据可以动态快速地更改。为了简化这个过程,我一直在开发一个声明性表指令 通常会有一些表,其中包含与之相关联的ID,比如客户机。我正试图在Id周围放置一个链接,这样当用户单击它时,他们将获得更多详细信息或指向不同的页面。插入DOM时,ng click和ui sref指令都不起作用 我已尝试实施此问题的解决方案: ///TABLE指令 常量表\u模板=` `; 类dctable控制器{ 添加列(列){ 如果(!this.columns){ this.columns=
ng click
和ui sref
指令都不起作用
我已尝试实施此问题的解决方案:
///TABLE指令
常量表\u模板=`
`;
类dctable控制器{
添加列(列){
如果(!this.columns){
this.columns=[];
}
这个.columns.push(col);
}
应用(列,行){
让fields=col.field.split(“,”);
让结果=”;
if(col.transform){
让$value=fields.length>1?
fields.map(field=>row[field]):
行[列字段];
返回col.transform({$value});
}否则{
返回fields.map(field=>row[field]).join();
}
}
}
函数dcTable(){
返回{
限制:“E”,
是的,
控制器:DcTableController,
controllerAs:“待定”,
模板:表格模板,
作用域:{},
bindToController:{
数据:“=”
}
};
}
//////////列指令
函数dcColumn(){
返回{
限制:“E”,
替换:正确,
需要“^dcTable”,
是的,
模板:“”,
范围:{
字段:“@”,
转换:&“
},
链接(范围、元素、属性、ctrl){
scope.transform=angular.isDefined(attrs.transform)?
scope.transform:false;
ctrl.addColumn(范围)
}
};
}
//////////编译指令
dcCompile.$inject=[“$compile”];
函数dcCompile($compile){
返回(范围、元素、属性)=>{
范围.$watch(
scope=>scope.$eval(attrs.dcCompile),
值=>{
html(值);
$compile(elem.contents())(范围);
}
);
};
}
//////////模块创建
类控制器{
构造函数(){
这是我的雇员=[
{
徽章编号:“1701”,
名字:“Jean Luc”,
姓:“皮卡德”,
工资:0
}
];
}
showAddress($活动、徽章){
控制台日志(徽章);
$event.preventDefault();
}
林卡(徽章){
设a=document.createElement(“a”);
a、 href=“#”;
a、 setAttribute(“ng click”`dc.showAddress($event,${badge})`);
a、 text内容=徽章;
返回a.outerHTML;
}
formatName(名称){
让[第一,最后]=姓名;
返回`${last},${first}`;
}
}
我发誓它曾经奏效过,但不管出于什么原因,我再也不能让它发挥作用了。以下是演示该问题的随附小提琴:
因此,当您在compile指令中对控制台进行一些日志记录时,您可以看到正在编译的元素的“内容”包括附加了ng click
的链接,但是当您单击链接时,它不会像应该的那样调用DemoController
中的函数
在标题中,我提到编译是在一个ng repeat循环中进行的。我真的不明白它为什么会影响指令的编译方式,但在我链接到的问题中,他们没有这样做,我也没有看到在repeat子句中实现该方法的任何其他示例。事实证明,我对repeat循环有预感。我的问题是,我编译到的
scope
实例没有dc
属性,因此当我单击它时,它找不到要运行的函数
为了解决这个问题,我必须编译到scope.$parent.$parent.$parent
范围
绑定到最里面的重复循环(tbl.列中的列
),第一个$parent
绑定到外部重复循环(tbl.数据中的行
),第二个$parent
绑定到表实例本身,第三个$parent
是包含表的作用域,因此将提供对showAddress
函数的访问
我觉得奇怪的是angular在找不到dc
或showAddress
时没有抛出错误,尽管我不太了解内部工作原理,不知道它如何决定调用什么
无论如何,这可能会帮助将来在处理重复循环时忘记说明父/子作用域的人。请在帖子中包含代码(最好是文本)。外部链接不能替代文章中的代码。
////////// TABLE DIRECTIVE
const TABLE_TEMPLATE = `<table class="table table-striped">
<thead>
<tr ng-transclude></tr>
</thead>
<tbody>
<tr ng-repeat="row in tbl.data">
<td ng-repeat="col in tbl.columns"
dc-compile="tbl.apply(col, row)"></td>
</tr>
</tbody>
</table>`;
class DcTableController {
addColumn(col) {
if (!this.columns) {
this.columns = [];
}
this.columns.push(col);
}
apply(col, row) {
let fields = col.field.split(",");
let result = "";
if (col.transform) {
let $value = fields.length > 1 ?
fields.map(field => row[field]) :
row[col.field];
return col.transform({ $value });
} else {
return fields.map(field => row[field]).join();
}
}
}
function dcTable() {
return {
restrict: "E",
transclude: true,
controller: DcTableController,
controllerAs: "tbl",
template: TABLE_TEMPLATE,
scope: {},
bindToController: {
data: "="
}
};
}
////////// COLUMN DIRECTIVE
function dcColumn() {
return {
restrict: "E",
replace: true,
require: "^dcTable",
transclude: true,
template: "<th ng-transclude></th>",
scope: {
field: "@",
transform: "&"
},
link(scope, elem, attrs, ctrl) {
scope.transform = angular.isDefined(attrs.transform) ?
scope.transform : false;
ctrl.addColumn(scope)
}
};
}
////////// COMPILE DIRECTIVE
dcCompile.$inject = ["$compile"];
function dcCompile($compile) {
return (scope, elem, attrs) => {
scope.$watch(
scope => scope.$eval(attrs.dcCompile),
value => {
elem.html(value);
$compile(elem.contents())(scope);
}
);
};
}
////////// MODULE CREATION
class DemoController {
constructor() {
this.employees = [
{
BadgeNo: "1701",
FirstName: "Jean-Luc",
LastName: "Picard",
Salary: 0
}
];
}
showAddress($event, badge) {
console.log(badge);
$event.preventDefault();
}
linkBadge(badge) {
let a = document.createElement("a");
a.href = "#";
a.setAttribute("ng-click", `dc.showAddress($event, ${ badge })`);
a.textContent = badge;
return a.outerHTML;
}
formatName(names) {
let [first, last] = names;
return `${ last }, ${ first }`;
}
}