使用动态ng-include和模板变量的ng-repeat范围问题

4

当ng-repeat包含具有变量的动态ng-include时,它不能正确地获取变量。

请参阅此plunker

主要HTML代码:

<table style>
  <tr>
    <th>Student</th>
    <th>Teacher</th>
  </tr>
  <tbody ng-repeat="val in data">
    <tr>
      <td>
        <div ng-include src="'profile.html'" onLoad="profile=val.student"></div>
      </td>
      <td>
        <div ng-include src="'profile.html'" onLoad="profile=val.teacher"></div>
      </td>
    </tr>
  </tbody>
</table>

profile.html代码

<span>Id - {{profile.id}}</span>
<span>Name - {{profile.name}}</span>

如果不使用ng-include链接,您可以看到它完美地工作。

P.S. 这是我实际想要实现的原型。 主要问题在于动态ng-include中使用的变量存在于ng-repeat中。

我已经查看了类似以下问题的内容,但没有得到任何答案。

1 2 3


你是说你在使用ng-include时无法看到数据,对吗? - Sa E Chowdary
@SaEChowdary:是的 - Somnath Muluk
ng-include确实会创建一个“新作用域”。https://github.com/angular/angular.js/wiki/Understanding-Scopes#ng-include。问题在于,首先您设置了option = val.student,然后是profile = val.teacher。 profile被覆盖了。您是否尝试过使用隔离作用域创建指令。这样您就不需要同时使用ng-include和ng-if了。 - Ravi Teja
3个回答

2
“ng-include”指令不会创建新的“$scope”对象,而是通过原型继承它,因此您的“profile”将被覆盖为另一个值。因此,首先您说“profile=theStudent”,然后用“profile=theTeacher”覆盖它,因此在两个模板中它总是设置为老师。有一个小技巧可以通过添加“ng-if='true'”来解决这个问题,它将创建一个新的“$scope”对象。
<tbody ng-repeat="val in data">
    <tr>
        <td>
            <div ng-include src="'profile.html'"
                 onLoad="profile=val.student"
                 ng-if="true"></div>
        </td>
        <td>
            <div ng-include src="'profile.html'" 
                 onLoad="profile=val.teacher"
                 ng-if="true"></div>
        </td>
    </tr>
</tbody>

请查看这个更新后的Plunker

这个可以正常工作。有没有不需要hack的方法?@devqon - Somnath Muluk
@SomnathMuluk 是的,请看我的回答。 - Ravi Teja

2

不要使用ng-includeng-if指令来达到你想要的效果,你可以创建一个简单的带有隔离作用域的profile指令,并将数据传递给它。

plucker

angular.module('ng-include-example', []).
controller("MainCtrl", function($scope) {

  var data = [
       {
         "student" : { "id":11, "name": "John" },
         "teacher" : { "id" : 21, "name": "Mike"}
       },
       {
         "student" : { "id":12, "name": "Tony" },
         "teacher" : { "id" : 22, "name": "Jack"}
       },
       {
         "student" : { "id":13, "name": "Cris" },
         "teacher" : { "id" : 23, "name": "Anthony"}
       },
       {
         "student" : { "id":14, "name": "Greg" },
         "teacher" : { "id" : 24, "name": "Reva"}
       }

    ];

    $scope.data = data;

})
.directive("profile", function(){
  return{
    restrict:'E',
    scope:{
      profile: "="
    },
    templateUrl: "profile.html"
  }
});

<div>
  Using Directive
  <table style>
      <tr>
        <th>Student</th>
        <th>Teacher</th>
      </tr>
      <tbody ng-repeat="val in data">
        <tr>
          <td>
            <profile profile = "val.student"></profile>
          </td>
          <td>
            <profile profile = "val.teacher"></profile>
          </td>
        </tr>
      </tbody>
    </table>
  </div>

0

你也可以创建一个名为profile.html的第二个HTML文件,然后在你的代码中使用:

index.html

<tbody ng-repeat="val in data">
        <tr>
          <td>
            <div ng-include src="'profile.html'" onLoad="profile=val.student"></div>
          </td>
          <td>
            <div ng-include src="'profile2.html'" onLoad="profile2=val.teacher"></div>
          </td>
        </tr>
      </tbody>

profile2.html

<span>Id - {{profile2.id}}</span>
<span>Name - {{profile2.name}}</span>

这将强制你维护两个具有相同内容的模板。 - devqon
我不想要有两个模板。这只是原型。我的模板中有很长的HTML。 - Somnath Muluk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接