添加了更新 2,见下文
首先,这是我正在使用的框架的起点(并且需要修复):
// index.html
<!doctype html>
<html ng-app="myApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="index.js"></script>
<body>
<div ng-controller="outerController">
<div id="copy"></div>
<hr>
<div id="src" ng-controller="innerController">
<table>
<th>Name</th>
<th>Type</th>
<tbody>
<tr ng-repeat="poke in pokemon">
<td>{{ poke.name }}</td>
<td>{{ poke.type }}</td>
</tr>
<tr>
<td>Pikachu</td>
<td>Electric</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
// index.js
var app = angular.module("myApp", []);
app.controller("innerController", function($scope) {
$scope.pokemon = [{
name: "Bulbasaur",
type: "Grass/Poison"
}, {
name: "Charmander",
type: "Fire"
}, {
name: "Squirtle",
type: "Water"
}];
});
app.controller("outerController", function($scope) {
$("#copy").html($("#src").html());
});
正如您所看到的,子 Controller 将通过 ng-repeat
从其作用域的数据生成一个表。这一步就成功了。下一步是父 Controller 将内部 HTML 从 src
复制粘贴到 copy
。目的是让 copy
包含由 angularJS 在 src
内完全生成的完整表的副本。
此步骤失败。仅表格标题和静态皮卡丘行可见。经过一些研究后,我确信这是因为 pokemon
位于子 Controller 的范围内,父 Controller 无法访问该范围。复制到 copy
容器中的 HTML 包含整个 ng-repeat
指令。这个复制的指令位于父作用域内,其中 $scope.pokemon
不存在/不包含任何数据,这就是为什么 ng-repeat
中的 copy
没有生成任何内容。
我无法将数据放入父 Controller 中。在我的实际应用中,系统采用了模块化设计。每个内部 Controller 代表一个模块,该模块从服务器提取自己的数据集。存在多个网页(以外部 Controller 为代表),这些网页与模块具有多对多的关系,并且每个网页中的模块的构成需要可修改。这意味着模块使用的数据必须包含在其自身内。
我该如何纠正这个问题?
更新 1:已编辑。我发布了一个使用 $emit
和 $on
的示例,但罗伯特的示例应该被认为是正确的,因为我对此还很陌生。引用他的回答。
更新 2:在测试 Alvaro Vazquez 和 Robert 的解决方案时,我已经确定了具体的根本原因。当执行 $("#copy").html($("#src").html());
时,复制的 ng-repeat
要么在任何数据传输到 outerController
之前执行,要么从未执行过。最后,修改我最初在上面所做的事情使其完全正常工作:
var app = angular.module("myApp", []);
$(function() {
$("#copy").html($("#src").html());
});
app.controller("innerController", function($scope) {
$scope.pokemon = [{
name: "Bulbasaur",
type: "Grass/Poison"
}, {
name: "Charmander",
type: "Fire"
}, {
name: "Squirtle",
type: "Water"
}];
});
app.controller("outerController", function($scope) {
$scope.pokemon = [{
name: "Bulbasaur",
type: "Grass/Poison"
}, {
name: "Charmander",
type: "Fire"
}, {
name: "Squirtle",
type: "Water"
}];
});
随着该特定语句的位置发生变化,剩下的就是将数据传输到 outerController
,此时 Alvaro 和 Robert 的解决方案都有效。
顺便说一句,我认为有些人建议不要使用 $("#copy").html($("#src").html());
。正如我在评论中部分描述的那样,我正在开发的实际应用程序由多个网页组成,每个网页都包含自己的 outerController
。每个 innerController
都位于其自己单独的 HTML 文件中,通过 include 指令添加到 src
中。 outerController
复制 src
的内部 HTML,将其传递给第三方库,该第三方库将其粘贴到 copy
并控制其视觉布局。 $("#copy").html($("#src").html());
实际上是第三方库实现的一部分,所以我无法更改它。因此,使用此语句是一项要求。
当我回家并且可以方便地使用 PC 键盘时,我会将上述内容作为解决方案发布。同时,如果您有更好的解决方案,请随时推荐,谢谢!
最佳答案
我认为你应该使用 Angular 服务。
声明服务
首先,您应该声明一个服务,它将数据“提供”给应用程序的其余部分。为了简单起见,我将只展示一个返回预定义数组的方法,但您可以在此处从服务器获取数据。
app.service('pokemonService', function () {
return {
getPokemon: function () {
return [{
name: "Bulbasaur",
type: "Grass/Poison"
}, {
name: "Charmander",
type: "Fire"
}, {
name: "Squirtle",
type: "Water"
}];
}
};
});
使用 Controller 中的服务
然后,您可以在任何 Controller 上使用该服务,将其作为任何其他预定义的 Angular 服务注入(inject):
app.controller('innerController', function($scope, pokemonService) {
$scope.pokemon = pokemonService.getPokemon();
});
app.controller('outerController', function($scope, pokemonService) {
$scope.outerPokemon = pokemonService.getPokemon();
});
在 View 中显示数据
最后,您可以在您想要的任何模板/模板的一部分中列出所有神奇宝贝:
<!doctype html>
<html ng-app="myApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="index.js"></script>
<body>
<div ng-controller="outerController">
<div id="copy">
<!-- Here you can also list the pokémon from your outerController, maybe this time in a list -->
<ul>
<li ng-repeat="poke in pokemonOuter">
{{ poke.name }} - <span class="type">{{ poke.type }}</span>
</li>
</ul>
</div>
<hr>
<div id="src" ng-controller="innerController">
<table>
<th>Name</th>
<th>Type</th>
<tbody>
<tr ng-repeat="poke in pokemon">
<td>{{ poke.name }}</td>
<td>{{ poke.type }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
总结
正如您所看到的,根本不需要搞乱 DOM。如果你使用 AngularJS,你应该以 Angular 的方式做事,直接使用 DOM 根本不是 Angular 的方式。相反,您应该将所有数据和业务逻辑放入服务中,然后在 Controller 中使用这些服务来检索该数据并将其传递给 View 。
关于javascript - 使用子作用域的数据作为父作用域的 ng-repeat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39350426/