添加了更新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());
});
正如您所看到的,子控制器将通过ng-repeat
从其范围的数据生成一个表。这一步很成功。下一步是让父控制器将内部HTML从src
复制粘贴到copy
。意图是copy
包含由src
内的angularJS完全生成的完整表的副本。
此步骤失败。只有表头和静态皮卡丘行可见。在做了一些研究后,我确信这是因为pokemon
位于子控制器的范围内,父控制器无法访问它。复制到copy
容器中的HTML包含整个ng-repeat
指令。此复制指令位于父作用域内,其中$scope.pokemon
不存在/不包含数据,这就是ng-repeat
中copy
未生成任何内容的原因。
我无法将数据放在父控制器中。在我的实际应用中,系统采用模块化设计。每个内部控制器代表一个从服务器提取自己的数据集的模块。有多个网页(由外部控制器表示)与模块具有多对多关系,并且每个网页中的模块组成需要可修改。这意味着模块使用的数据必须包含在其自身内。
我该如何纠正这个?
更新1 :已编辑。我发布了一个使用$emit
和$on
的示例,但罗伯特的例子应该被认为是正确的,因为我还是很陌生。请参阅他的回答。
更新2 :在测试Alvaro Vazquez&amp; amp;&amp;罗伯特的解决方案,我已经确定了具体的根本原因。执行$("#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键盘的便利性时,我会将上述内容作为解决方案发布。在此期间,如果你有一个,可以随意推荐更好的解决方案,谢谢!
答案 0 :(得分:2)
我认为你应该使用角度服务。
首先,您应该声明一个服务,该服务将“提供”给您应用程序的其余部分的数据。为简单起见,我只会显示一个返回预定义数组的方法,但您可以在此处从服务器获取数据。
app.service('pokemonService', function () {
return {
getPokemon: function () {
return [{
name: "Bulbasaur",
type: "Grass/Poison"
}, {
name: "Charmander",
type: "Fire"
}, {
name: "Squirtle",
type: "Water"
}];
}
};
});
然后,您可以在任何控制器上使用该服务,将其作为任何其他预定义的角度服务注入:
app.controller('innerController', function($scope, pokemonService) {
$scope.pokemon = pokemonService.getPokemon();
});
app.controller('outerController', function($scope, pokemonService) {
$scope.outerPokemon = pokemonService.getPokemon();
});
最后,您可以在所需模板的任何模板/部分中列出所有神奇宝贝:
<!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方式。相反,您应该将所有数据和业务逻辑放入服务中,然后在控制器中使用这些服务来检索该数据并将其传递给视图。
答案 1 :(得分:0)
Angular中的作用域使用原型继承,因此子作用域可以访问父属性,但父作用域不能访问子控制器作用域属性。
您可以使用服务共享数据或使用$ emit向上发送事件(向上直到根范围)。
我为你创建了一个plnkr来向你展示如何使用emit(你可以找到它here)
var app = angular.module("myApp", []);
app.controller("outerController", ['$scope', function($scope) {
console.log('aici');
$scope.$on('pokemonEvent', function(event, mass) { console.log(mass); });
}]);
app.controller("innerController", ['$scope', function($scope) {
$scope.pokemon = [{
name: "Bulbasaur",
type: "Grass/Poison"
}, {
name: "Charmander",
type: "Fire"
}, {
name: "Squirtle",
type: "Water"
}];
$scope.$emit('pokemonEvent', $scope.pokemon);
}]);