Utilized controller's isolated scope inheritance to enhance the reusability of the directive

How can I create an isolated scope in a controller to make a reusable directive? Take a look at my code snippet below:

(function (app) {
    // Declare the Template
    var template = function (element, attrs) {
        var htmltext =

            '<select ' + attrs.type +
            ' ng-init="getAll(\'' + attrs.classname +
            '\');" ng-model="' + attrs.model +
            '" ng-options="value.' + attrs.data +
            ' for value in result"></select>';

        return htmltext;
    };

    app.directive('listData', function () {
        return {
            restrict: 'E',
            controller: 'listController',
            controllerAs: 'vm',
            scope: { vm: '=' },
            template: template
        }
    });

}(angular.module('app')));

Is it possible to utilize this directive multiple times with just one controller and access the resulting data from controller functions? In the example provided, there is a getAll function that returns $scope.result from the controller to the caller. This returned result is intended to be used with the ng-model assigned to each directive.

<div ng-controller="listController">
        <list-data type=""
                   model="person"
                   classname="Person"
                   data="Family" 
                   vm="listController">
        </list-data>
<list-data></list-data>
        <p>{{person.Name}} {{person.Family}}?</p>

Here is the list controller:

(function (app) {

    app.controller('listController', ['$scope','myservice',function ($scope, myservice) {

        // Call GetAll Method From Each Class
        $scope.getAll = function (classname) {
            myservice.getAll(classname)
                .success(function (data, status) {
                    $scope.result = data;
                    $scope.status = status;
                })
                .error(function (data, status) {
                    $scope.result = data;
                    $scope.status = status;
                });
        }   
}(angular.module('app')));

And here is the service:

(function (app) {
    app.factory('myservice', function ($http,$q) {
        return {
            getAll: function (classname) {
                try {
                    return $http.get('/api/' + classname + '/GetAll/');
                } catch (e) {
                    window.alert(e.message);
                    // Should send an error to controller
                }
            }
        }
    });
}(angular.module('app')));

Answer №1

Is this the solution you are looking for?

(function (app) {
    //defining the Template
    var template = function (element, attrs) {
        var htmltext =

            '<select ' + attrs.type +
            '  ng-model="model" ng-options="value as value[data] for value in from"></select>';

        return htmltext;
    };

    app.directive('listData', function () {
        return {
            restrict: 'E',
            scope: { data: '@',
                     classname:'@',
                     model:'=',
                     from:'=',
                     type:'@',
                     data:'@'
                   },
            template: template,
            replace:true,
        }
    });
    app.controller('TestController', ['$timeout', '$scope', function($timeout, $scope){
       $scope.data = [];
       $timeout(function(){
         $scope.data = [{Family:"FOO", Name:"foo"},{Family:"BAR", Name:"bar"}];
       });// simulate async fetching
    }])
}(angular.module('app', [])));
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="TestController">
         <h1> this is a test </h1>
         <list-data type=""
                   model="person"
                   classname="Person"
                   from="data"
                   data="Family">
        </list-data>

        <p>{{person.Name}} {{person.Family}}?</p>
  
  </div>
  </div>

Your directive had some errors:

  1. You were trying to select a person and show their Family in the <select>. For that, you need to use the optional as in the ng-options.
  2. To properly utilize an isolated scope, you should bind your data to it instead of using attributes, especially if you want your list to be dynamic and your directive to update accordingly.

What I added :

  1. An additional 'from' attribute to your directive, specifying the list of persons you want to choose from.
  2. The TestController functions as your listController although it simulates asynchronous data retrieval.

What I removed :

  1. The call to getAll in your directive, which should handle selecting an element from a list based on specified parameters, not where the data is fetched from. This logic belongs in the controller of the view and has been replaced by the 'from' attribute. If you still prefer handling this within your directive, you can use the link(scope, element, attrs){} function to fetch data and bind it to the scope.

EDIT : Per request, you can bind attributes to the scope in the link function like this, but note that it's only for reading the data, not changing it:

link:function(scope, element, attrs){
    scope.value = attrs.myAttr;
    attrs.$observe('myAttr', function(){
      scope.value = attrs.myAttr;
    });
}

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

Attempting to assign a value in ng-init that was only established after loading the model and making two AJAX calls

Let me explain, The project I'm currently working on involves a spinoff of phonegap. I am facing a situation where I need to wait for an AJAX response before setting the ng-init value. Typically, you can set it like this: ng-init = "ng-model = arr[0] ...

Uncovered event listener in Angular tests

Imagine having a custom directive: angular.module('foo').directive('myDir', function () { return { restrict: 'E', link: function (scope) { var watcher = scope.$watch('foo, function () {}); scope.$on ...

Validation and promises in the world of AngularJS

Validation of a form in an Angular app involves using a custom JavaScript function before submission. Depending on a condition, a confirmation dialog needs to be displayed to the user, requiring them to confirm or reject it before proceeding with validatio ...

javascript triggering before its designated event happens

I've encountered a puzzling issue with a complex file where a javascript function is behaving unexpectedly—it seems to be firing before its designated event actually takes place. I have ruled out the possibility of an onload event triggering this be ...

Managing value state with several Formik forms within a single component

I'm currently in the process of constructing a web page using React and Formik. Within this form page, I have integrated three distinct Formik forms that are conditionally displayed based on a switch statement. The reason behind structuring it this wa ...

Steps for retrieving the currently selected text inside a scrolled DIV

An imperfect DIV with text that requires a scroll bar For example: <div id="text" style='overflow:scroll;width:200px;height:200px'> <div style='font-size:64px;'>BIG TEXT</div> Lorem Ipsum is simply dummy text of th ...

Unable to submit value on Ajax-powered dynamic select form

I need help with a dynamic Select element inside a form that is not submitting its value. Here is the code snippet: <table> <form> <tr> <td><select>(options values)</select></td> <td id='fill'>< ...

Tips for creating an Instagram photo collection on your own blog

Currently, I am on a quest to discover and either personalize or construct my very own Instagram photo gallery for the purposes of my personal blog website. The ownership of the website is fully mine which implies that I have the liberty to write PHP code ...

issue with bootstrap modals single firing when using remote data source

I am facing an issue with my table that contains a list of items, each item having a <select> element with different statuses. Here's how the process is supposed to work: Upon changing the status, a modal should pop up. The modal suc ...

What could be causing the syntax error I'm encountering while trying to extract data from this JSON file?

I've been encountering a syntax error in my console that reads "Uncaught SyntaxError: Unexpected token '}'. I've checked my JavaScript code, but being new to coding, I'm not sure why this is happening. Could the error be on the JSO ...

Ways to showcase various links in Angular based on API response

I am currently learning Angular and exploring how to convert an ASP.NET application into Angular. My goal is to dynamically display different links to users based on their group membership. I have a Web API (ASP.NET Web API) that can provide user informati ...

Utilizing react.js and passing props as parameters in recursive functions

When using recursion, I encountered an issue where I am unable to pass the props parameter: class App extends React.Component { constructor(props) { super(props); this.state = { visible: this.props.root, a:this.props.a }; } toggle(){ thi ...

What is the reason behind the lack of data sharing among controllers in my service?

I have created a factory to retrieve data from the Database and pass it to all controllers in my application, like so: (function () { angular.module('appContacts') .factory('dataService', ['$http', dataService]); ...

After making a selection from the list, I would like to automatically close the select menu

<div class="topnav__menu"> <button class=" topnav__button topnav__button--has-arrow topnav__menu-button " type="button" id="hideselectOptio ...

Encountered an issue with the response - SyntaxError: Unexpected end of input while utilizing the 'no-cors' mode

I attempted a Fetch call in ReactJS to a REST-API and am trying to manage the response. The call is successful, as I can see the response in Chrome Dev Tools: function getAllCourses() { fetch('http://localhost:8080/course', { method: 'P ...

Searching with Jquery Ajax

For my search functionality, I am utilizing ajax jquery js. I found this useful code snippet here: However, I am facing some challenges with the following Javascript code: <script language="JavaScript" type="text/javascript"> <!-- function searc ...

How to implement a pop-up dialog box with multiple input boxes using AngularJS?

If you click on the link below: https://material.angularjs.org/latest/demo/dialog You'll notice that the prompt dialog box features only one input field. I'm curious to know if it's possible to customize this using mdDialog to include mult ...

A step-by-step guide on sending a question to an MS Azure chat bot through the direcline channel using client-side scripting techniques

Currently, I am utilizing the Azure Chat bot (v4 MS bot framework) and integrated it into the Direcline channel. My goal is to send a question to the chatbot when a user clicks on one of the suggested questions. In the image below, you can see the list of ...

How to dynamically insert a hyperlink inside a <td> element within a table using JavaScript

What is the best way to create a hyperlink in a <td> within a dynamic table? I want the first <td> to be a link that combines a URL with the cell value. This is how the dynamic table is created: for (var i = 0; i < riskData.length; i++) { ...

In Next.js, encountering an error when using canvas drawImage

I am attempting to upload a local image onto a canvas element, but I keep encountering an error: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement ...