繁体   English   中英

如何根据父控件的范围生成子控制器?

[英]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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM