简单的动态指令(带有动态控制器和作用域)

Simple dynamic directives (with dynamic controllers and scope)?

本文关键字:动态 控制器 作用域 动态控制 指令 简单      更新时间:2023-09-26

我觉得应该是一个相当简单的问题。我正在一个TypeScript + Angular的应用中工作。

在控制器中,我有一个我想使用的类似directives的数组。这些是我在整个应用程序中使用的panels

我将给它们各种属性,如controller, templateUrl, data等。它们在我的控制器中看起来是这样的:

public panels: IPanelConfig[] = [
    {
        controllerName: "MenuController",
        templateUrl: "menu/menu.html",
        data: // an object with some boring stuff in it
    },
    {
        controllerName: "AnotherController",
        templateUrl: "another/this/is/arbitrary.html",
        data: {}
    }
];

在我的view中,我循环遍历每个panel,并使用称为panel的通用directive来处理其余的工作。像这样:

<div ng-repeat="panel in vm.panels">
    <div panel
         paneldata="panel.data"
         templateurl="panel.templateUrl"
         ctrl="panel.controllerName"></div>
</div>

我的自定义panel指令看起来像这样:

module App {
    "use strict";
    export class Panel {
        public link:(scope:angular.IScope, element:angular.IAugmentedJQuery, attrs:angular.IAttributes) => void;
        public restrict:string = "EA";
        public controller:string = "@";
        public name: string = 'ctrl';
        public replace:boolean = true;
        public scope:any = {"paneldata": "="};
        constructor() {
            console.log("panel directive constructor");
        }
        public compile(el, attrs){
            el.append("<div ng-include=''"components/panels/" + attrs.templateurl + "'"'>");
        }
    }
    // add the directive to the angular module
    angular.module("app").directive("panel", [() => new App.Panel()]);
}

最后,我设置了一个动态控制器。在本例中,它是MenuController。它很无聊,看起来像这样:

module App {
    "use strict";
    export class MenuController {
        public scope: any = null;
        public items: IMyItems[] = null;
        public panelData: any = null;
        public dataService: IDataService = null;
        static $inject = ["$scope", "DataService"];
        constructor($scope: any, DataService: IDataService) {
            $scope.vm = this;
            this.scope = $scope;
            this.dataService = DataService;
            $scope.$watch("paneldata", (v) => { this.panelData = v; });
            this.init();
        }
        public init() {
            this.dataService.someRequestToGetItems().then((results) => {
                this.items = results; // <--- the problem!!! :(
            });
        }
    }
    // add the controller to the module
    angular.module("app").controller("MenuController", App.MenuController);
}
在这一点上,所有都像我期望的那样工作。panelData被填充,适当的viewcontroller被使用,似乎我是如此接近,但它还没有完全在那里。

问题:问题是当我尝试在MenuControlleritems数组上使用ng-repeat时。视图的行为就好像items是空的(它不是——一个简单的console.log()证明它包含了我所期望的)。

值得注意的

: 我最初建立了一个具有相同功能的Menu指令。view,获取items的请求和循环能力,接受panelData属性等都工作得很好。直到我试图让它更有活力时,我才遇到了麻烦。

我真正想要的:对我来说,当每个面板都有自己的指令时,有这个额外的panel指令来漏斗似乎很愚蠢(这是我开始的方式)。我真正想要做的是:

<div ng-repeat="panel in vm.panels">
    <div {{ panel.directiveName }} paneldata="panel.data"></div>
</div>

但这行不通。

我希望有任何建议或指导!


我有一种预感,这个问题可能与scope有关,但我添加了:

public test: string = "A test";

到我的MenuController,并成功地显示在我的视图

嗯…这并没有完全解决"为什么这个不工作"的问题,我最初问(我觉得愚蠢的不尝试这个前一段时间),但另一种方法来解决我的问题(和处理动态指令/控制器),是添加:

el.append("<div " + attrs.directivename + " paneldata='" + attrs.paneldata + "'></div>");

到我的panel指令的compile()函数,而不是用ng-include做模板。我仍然需要一个指令"漏斗",但这将解决我的问题,现在(并希望其他人谁偶然发现这个!)。