Angularjs 韩元';当从ng repeat循环放入DOM时,不能编译

Angularjs 韩元';当从ng repeat循环放入DOM时,不能编译,angularjs,Angularjs,在工作中,我必须显示许多表,其中的数据可以动态快速地更改。为了简化这个过程,我一直在开发一个声明性表指令 通常会有一些表,其中包含与之相关联的ID,比如客户机。我正试图在Id周围放置一个链接,这样当用户单击它时,他们将获得更多详细信息或指向不同的页面。插入DOM时,ng click和ui sref指令都不起作用 我已尝试实施此问题的解决方案: ///TABLE指令 常量表\u模板=` `; 类dctable控制器{ 添加列(列){ 如果(!this.columns){ this.columns=

在工作中,我必须显示许多表,其中的数据可以动态快速地更改。为了简化这个过程,我一直在开发一个声明性表指令

通常会有一些表,其中包含与之相关联的ID,比如客户机。我正试图在Id周围放置一个链接,这样当用户单击它时,他们将获得更多详细信息或指向不同的页面。插入DOM时,
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 }`;
  }
}