Are you looking for straightforward dynamic directives that come with dynamic controllers and a scope?

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.

Answer №1

Although this solution may not directly address the initial question of why something isn't working as expected (which in hindsight seems like a simple fix that should have been tried earlier), I discovered another approach to resolving my issue by incorporating the following code snippet:

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

into the compile() function of my panel directive instead of using an ng-include template. While I still need to implement a directive "funnel", this alternative method should provide a temporary workaround for my problem (and hopefully benefit others facing similar challenges).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

TestCafe has encountered an issue: "There are no tests available to run. This may be due to either the test files not containing any tests or the filter function being too

Attempting to run automated tests using TestCafe resulted in an error when executing the following command. testcafe chrome testc.ts The specified command was used to test the testc.ts file within my Angular application, with TestCafe installed globally ...

Should a MEAN stack app require the use of two servers in order to run?

Currently, I am in the process of developing a MEAN stack application which involves using MongoDB, ExpressJs, Angular 6, and NodeJs. One issue I am facing is determining whether two servers will be necessary to run the app simultaneously. Specifically, o ...

Conceal the Addon Tab across all pages in Storybook

Is there a way to globally hide an Addon Tab without disabling the addon itself? Specifically, I am using version 5.3.18 of Storybook with React and I want to hide the tab panel from the addon "styled-component theme". I apologize for the basic question, ...

Determining When to Activate Button Based on Angular - Verifying That All Choices Have Been Ch

This quiz application requires the user to choose options before proceeding to the next page, with the next button being disabled by default. Once all options are chosen, the next button should become enabled. NOTE: Although the functionality for selecti ...

Proxy/firewall causing interference with socket connection from chrome extension

I have encountered an issue with my web app in JavaScript that connects to a socket using socket.io and a Chrome Extension that also connects in the same way to the same server. While everything works smoothly on most computers and internet connections, th ...

Issue occurred when trying to load controllers during the migration process from AngularJS1 to Angular6

Currently, I am in the process of upgrading AngularJS1 components to Angular6. My strategy involves creating wrappers for all existing AngularJS1 components by extending "UpgradeComponent" and storing them under the folder "directive-wrappers". However, wh ...

Angular Components unexpectedly lose background transparency when using Transparent-Background-PNG in the foreground

Hey there! I'm currently working on a landing page and I have this amazing idea to use a stunning picture of clouds with a transparent background layered over a beautiful landscape. The only problem is that when I try to implement it, the transparency ...

What is the solution to resolving a Typescript error within an imported library?

I've encountered a Typescript error that I'm unable to resolve because it doesn't originate from my code. The issue arises when I import a NextJs/React module named next-seo and use it as instructed: <NextSeo config={seoConfig} /> The ...

Error: Unable to execute function on blog mapping

I am facing an issue with my app where it fails to detect objects. Every time the component in my app calls ".map", I encounter an error message. I have double-checked that index.js is passing props correctly. Can anyone explain why this problem is occurri ...

What steps can be taken to resolve webpage loading issues following data insertion into a database using express and node?

My express app has a post route handler (/addpost) for adding data to a database. Everything works perfectly, but the window keeps loading. To prevent the browser from waiting for more data, I know I need to send a response. However, all I want is for th ...

Scroll automatically to the following div after a brief break

On my website, the title of each page fills the entire screen before the content appears when you scroll down. I am interested in adding a smooth automatic scroll feature that will transition to the next section after about half a second on the initial "ti ...

Encountered an issue while trying to create a new controller in Angular, where the error indicated

Apologies for any language errors in advance. I recently delved into angular using the MEAN stack (MongoDB, Express, Angular, Node) and encountered an issue. Every time I try to create a simple Controller, I keep getting this error: Argument 'test ...

What are the steps to implementing a JavaScript WebWorker in a webpack environment?

Struggling to implement web workers in my web app and encountering difficulties. The addition of a new entry to the webpack.config.js file is not producing desired results. Attempting to utilize the npm package named worker-loader, however, facing challen ...

Having trouble sending an array from Flask to a JavaScript function

As a newcomer to web development and JavaScript, I'm struggling to pass an array from a Flask function into a JavaScript function. Here's what my JS function looks like: function up(deptcity) { console.log('hi'); $.aja ...

Asynchronous waiting waits not for async await

I'm currently working on a function that loops through an array and updates the model for each ID, then adds the result to another array. This is the code snippet I have: async function getSortedAnimals() { var i = 0; var sortedAnimals = []; id ...

Dealing with a frustrating roadblock in Three.js where you encounter an "Unknown format" error while trying to work with

Greetings, I am relatively new to THREE.js and currently experimenting with loading a .FBX Object using the FBXLoader found in three/examples/jsm/loaders/FBXLoader while integrating this into React.js. Upon launching the page, I encountered an issue where ...

Material UI - Array of Chips

I have been working on creating a ReactJS component that displays an array of chips with unique styling for each one. To achieve this, I created individual makeStyles classes for the chips. However, I encountered difficulties in dynamically changing the cl ...

Is there a way to ensure that a certain block of code in Typescript is executed only after an API call has been completed?

When making an API call, I need the code after the call to wait until the API call finishes. In my function called this.api_call, it calls the API and only returns an array returnValue once the call is complete. let returnValue = this.api_call(data); // ...

Utilizing group by date feature in Angular ag-Grid

I'm working on setting up an ag-grid with columns for date, time, and location. Below is the code snippet: list.component.ts columnDefs: any = [{ headerName: 'Date', field: 'date', valueFormatter: (data: any) => { ...