Feeling like I have a simple problem to solve here. Working within the confines of a TypeScript + Angular application.
Within a controller, I've got an array of similar directives
that I want to utilize. These are essentially the panels
strewn throughout my app.
I assign attributes such as controller
, templateUrl
, data
, etc. Looks something like this in the controller:
public panels: IPanelConfig[] = [
{
controllerName: "MenuController",
templateUrl: "menu/menu.html",
data: // object with some mundane info
},
{
controllerName: "AnotherController",
templateUrl: "another/this/is/arbitrary.html",
data: {}
}
];
In my view
, I iterate through each panel
using a generic directive called panel
which handles the heavy lifting. It goes a little like this:
<div ng-repeat="panel in vm.panels">
<div panel
paneldata="panel.data"
templateurl="panel.templateUrl"
ctrl="panel.controllerName"></div>
</div>
This custom panel
directive is structured as follows:
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 + "\"'>");
}
}
// include directive to the angular module
angular.module("app").directive("panel", [() => new App.Panel()]);
}
To wrap it up, one of the dynamic controllers is all set up. In this instance, we're talking about MenuController
. It's pretty basic and looks like this:
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 issue! :(
});
}
}
// add the controller to the module
angular.module("app").controller("MenuController", App.MenuController);
}
At this juncture, everything seems to be falling into place just as expected. The panelData
gets filled, the correct view
and controller
are implemented, and it feels like success is around the corner, but not quite there yet.
The Issue:
The hitch arises when attempting to use an ng-repeat
on the MenuController
's items
array. The view acts as if the items
is empty (even though a quick console.log()
would confirm otherwise).
Important to Note:
Initially, I had developed a Menu
directive with identical behavior. The view
, request to fetch items
, and ability to iterate through, managing a panelData
attribute, all worked flawlessly. The struggle only arose when I tried to make things more dynamic.
What I'm Truly After:
It strikes me as unnecessary to have this additional panel
directive for passing through when each panel could simply have its own directive (which was initially how I approached it). What I really want is the ability to do something like this:
<div ng-repeat="panel in vm.panels">
<div {{ panel.directiveName }} paneldata="panel.data"></div>
</div>
But alas, it doesn't work.
Any suggestions or guidance would be greatly appreciated!
Update
Felt like the issue might boil down to scope
, so I added:
public test: string = "A test";
to my MenuController
and successfully displayed it in my view.