如何基于父控件的作用域生成子控制器
How do I generate child controllers based on the scope of a parent control?
我正在设计一个显示面板列表的界面,每个面板都有自己的模型。我希望能够渲染每个面板,使其使用父控制器中的模型拥有自己的模型。
类似于:
function Parent() {
this.panels = [{name: "Foo", place: "Bar"}, {name: "Hello", place: "World"}];
}
function Child(model) {
var model = model //{name: "Foo", place: "Bar"}
}
for (var i = 0; i < Parent.panels.length; i++) {
new Child(Parent.panels[0]);
}
我的问题是:在"棱角分明的心态"下,解决这个问题的最佳方法是什么?
我目前的计划如下。我将有两个控制器,一个用于面板列表,另一个用于每个单独的面板。所以,像这样的东西:
angular.module("panelApp", [])
.service("panelService", function() {
var panels = [/* panel classes */];
return {
getPanels: function() { return panels }
}
})
.controller("PanelListCtrl", ["$scope", "panelService", function($scope, panelService) {
$scope.panels = panelService.getPanels();
$scope.currentPanel = $scope.panels[0];
})
.controller("PanelCtrl", ["$scope", "panelService", function($scope, panelService) {
//this is where stuff gets hazy
for (var i = 0; i < PanelListCtrl.panels.length; i++) {
//generate child panels... somehow... =(
}
})
我显然做得不对,但总的想法是,我希望能够封装列表和每个单独面板的功能。
我想出的另一种方法是使用指令:
angular.module("panelApp", [])
.service("panelService", function() {
var panels = [/* panel classes */];
return {
getPanels: function() { return panels }
}
})
.controller("PanelListCtrl", ["$scope", "panelService", function($scope, panelService) {
$scope.panels = panelService.getPanels();
$scope.currentPanel = $scope.panels[0];
})
.directive("panel", function() {
require:"PanelListCtrl",
restrict: "E",
link: function(scope, element, attrs, panelListCtrl) {
for (var i = 0; i < panelListCtrl.panels.length; i++) {
//generate markup... somehow. How can one create directive markup in the DOM on the fly??
}
},
templateUrl: "template.html"
})
我已经和这个黑社会抗争了至少一个小时了。请帮忙。
注意事项
我忘了提的是,显示的面板数量是可变的。因此,加载页面时DOM中没有标记,必须动态注入。我是angular的新手,不知道如何根据框架使用的MV*方法向页面动态添加元素。
这应该会让您开始:http://plnkr.co/edit/b7KbXMPWOhAG50ajYyYN?p=preview
您的基本想法是合理的,使用分层作用域,它可以在控制器中使用作用域继承,也可以在控制器和指令之间实现。既然我怀疑您需要的主要是UI,那么您最好定义一个指令。
此外,在动态生成模板时,您可能想要的是一个静态模板,用于填充所需值的面板。然后,您可以使用ng-repeat
来生成其中的许多。
控制器
.controller("PanelListCtrl", ["$scope", "panelService", function($scope, panelService) {
$scope.panels = panelService.getPanels();
// Saving the `isActive` property in the model, keeping the controller thin.
$scope.panels[0].isActive = true;
// This will manage the selection of the correct panel.
$scope.selectPanel = function (panel) {
$scope.panels.forEach(function (p) {
p.isActive = p === panel;
});
};
}])
.directive("panel", function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
scope.$watch(attrs.panel, function (newVal) {
scope.panel = newVal; // <-- watch and populate the `panel` in the current scope.
// The directive cam be made to
// work even without this link function (because of scope
// inheritence) but the best-practise is to keep the directives
// as loosely coupled with the controller as possible.
// In this case, you'll be free the name the panel variable anything
// in the controller as long
// as you pass the variable to the directive: <div panel="nameOfPanel"></div>
})
},
templateUrl: "panel.html" // <-- template is here for One of the panes.
}
})
模板
<body ng-controller="PanelListCtrl">
<div ng-repeat="p in panels">
<button ng-click="selectPanel(p)">Select panel {{$index}}</button>
<div panel="p"></div>
</div>
</body>
相关文章:
- 正在$rootScope上达到控制器作用域$在内部控制器上
- 从指令链接函数监视控制器作用域
- 控制器作用域变量在刷新之前未加载
- AngularJS:如何在指令范围的对象发生变化时更新与控制器作用域相关联的控制器作用域
- ng-click 指令不调用控制器作用域中定义的函数
- 如何从2级指令访问控制器作用域
- 角度指令控制器作用域继承
- 触发指令AngularJs的控制器作用域
- Angularjs-在路由更改时刷新控制器作用域
- 访问父指令's子指令中的控制器作用域变量
- 将Angular Service对象绑定到控制器作用域并更新
- UI引导日期选择器不调用内联控制器作用域上的函数
- 将变量从控制器作用域传递到指令
- 工厂中与控制器作用域绑定的已修改数据不会更新
- 带有双向绑定的孤立作用域指令不能反映控制器作用域的变化
- 如何在angular 1.4.5+中操纵指令中的控制器作用域
- AngularJS:在两个具有隔离作用域的指令之间共享一个控制器作用域
- 如何将控制器作用域变量传递给angular.元素在头部元素中追加子元素时
- AngularJS+Jasmine -在指令中写入一个控制器作用域
- 如何从嵌入式D3脚本中访问Angular控制器作用域