What is the correct way to bind an object in the 'bindings' using $compile in Angular.js 1.0?

I am looking to dynamically compile a component and insert it into a specific DOM element, which is also dynamically created by a third-party library. To achieve this, I am utilizing the $compile and $scope.

https://jsbin.com/gutekat/edit?html,js,console,output

// ListController $postLink life cycle hook

function $postLink() {
  ...

  $timeout(function () {
    ctrl.items.splice(0, 1);
    $log.debug('First item of array is removed');
    $log.debug(ctrl.items);
  }, 2000);
}

However, the $onChanges life cycle hook in the ListItemController is not being executed.

// ListItemController $onChanges life cycle hook

function $onChanges(changes) {
  if (!changes.item.isFirstChange()) {
    $log.debug(changes);  // Not executed
  }
}

I suspect that using angular.merge to pass the item before initializing the ListItemController controller instance is causing this issue.

var itemScope = $scope.$new(true, $scope);
itemScope = angular.merge(itemScope, {
  $ctrl: {
    item: item
  }
});

Answer №1

I made some adjustments to your code to illustrate the concept of one-way binding.

angular.module('app', [
    'list.component',
    'list-item.component'
]);

/**
 * list.component
 */
angular
    .module('list.component', [])
    .component('list', {
        controller: ListController,
        template: '<div id="list"></div>'
    });

ListController.$inject = ['$compile', '$document', '$log', '$scope', '$timeout'];
function ListController($compile, $document, $log, $scope, $timeout) {
    var ctrl = this;

    ctrl.$onInit = $onInit;
    ctrl.$postLink = $postLink;

    function $onInit() {
        ctrl.items = [
            {
                id: 0,
                value: 'a'
            },
            {
                id: 1,
                value: 'b'
            },
            {
                id: 2,
                value: 'c'
            }
        ];
    }

    function $postLink() {
        var index = 0;

        var iElements = ctrl.items.map(function (item) {
            var template = '<list-item item="$ctrl.items[' + (index) + ']"></list-item>';
            index++;

            return $compile(template)($scope.$new(false));
        });

        var listDOM = $document[0].getElementById('list');
        var jqListDOM = angular.element(listDOM);

        iElements.forEach(function (iElement) {
            jqListDOM.append(iElement);
        });

        $timeout(function () {
            ctrl.items[0] = { id: 3, value: 'ss' };
            ctrl.items[1].value = 's';
            ctrl.items[2].value = 's';
        }, 2000);
    }
}

/**
 * list-item.component
 */
angular
    .module('list-item.component', [])
    .component('listItem', {
        bindings: {
            item: '<'
        },
        controller: ListItemController,
        template: '<div class="listItem">{{ $ctrl.item.value }}</div>'
    });

ListItemController.$inject = ['$log'];
function ListItemController($log) {
    var ctrl = this;

    ctrl.$onChanges = $onChanges;

    function $onChanges(changes) {
        if (!changes.item.isFirstChange()) {
            $log.debug(changes);    // Not executed      
        }
    }
}

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

Retrieving a value attribute from the isolated controller of a directive

I have a directive that reads and writes attributes, but I'm having trouble getting it to work as expected. The issue seems to be with the controller inside main-directive.js, which is empty, while the actual action is happening in the isolated direct ...

Struggling to delete a table row using jquery

Currently, I am encountering an issue with removing a specific "tr" element within a table using jQuery. Here's the situation: I have a table where rows are clickable. Upon clicking on a row, I can update the data associated with that particular obj ...

What is the method for extracting the value of a JavaScript variable using the .Net framework or C# programming language?

Looking at the code snippet below, I am trying to extract the values of title and videoId. These elements are part of the session, which is nested within units. I am unsure how to retrieve their values using C# or the .Net framework. Can anyone help m ...

Feeling trapped by the endless stream of AJAX calls

As I was working on building a scheduler with jQuery and AJAX, I encountered a problem with multiple AJAX requests. Although most of the time everything works fine and returns the correct values, occasionally, out of more than 50 requests, I come across so ...

Experience the dynamic bouncing marker feature in Next.js React-Leaflet with the powerful tool Leaflet.SmoothMarkerB

I'm a beginner in front-end development and I'm attempting to create a bouncing marker in React-leaflet using the leaflet.smooth_marker_bouncing plugin version 1.3.0 available at this link. Unfortunately, I couldn't find enough documentation ...

Methods to maintain the select2 dropdown event open while interacting with another select2 dropdown

I have a situation where I need to dynamically add a class to a div whenever a select2 dropdown is open. To achieve this functionality, I am utilizing the open and close events of select2. The current code successfully adds the class when opening a selec ...

Safari iOS 8 experiencing issues with loading WebGL image textures

The example mentioned above runs smoothly on all major browsers, including Safari on Mac OS. However, it fails to display the correct image on my iPad running the latest iOS 8. Click here for the example. Similarly, the tutorial provided in the following ...

Having trouble getting AngularJs ng-repeat to function properly when using multiple items in ng-init?

Just getting started with AngularJs and running into an issue with ng-init and ng-repeat in the example I'm working on. Below is a snippet from my code within the body section: <div ng-app="" ng-init="books=[ {title:'Pride and Prejudice&a ...

The @click directive in vuex does not function properly within the Vue component

This content is from my online shop. getters: { getFormattedUsers (state) { state.users.forEach(v => { v.fullname = `${capitalize(v.fname)} ${capitalize(v.lname)}` v.created_from_now = moment(v.created_at).fromNow() v.approve_but ...

Adding a backslash in Angular: Tips and Tricks

I have a question about adding a backslash to a string that is returned from a div, for example Car1 \sold. Although I am able to retrieve the status, I am having trouble adding the backslash. Here is what I have tried so far: <span>{{addBackl ...

Stop const expressions from being widened by type annotation

Is there a way to maintain a constant literal expression (with const assertion) while still enforcing type checking against a specific type to prevent missing or excess properties? In simpler terms, how can the type annotation be prevented from overriding ...

Can data be presented in AngularJS without the use of scope variables?

I have a method: <span ng-init="getJobApplicantsList(jobId)">(number should be display here)</span> Is there a way to display the data without having to store it in a scope variable? I need to use this method in many places. This is my cont ...

C# variable value not being retrieved by jQuery

When I implemented the jQuery scripts in my .aspx file, everything worked perfectly. Here is the code snippet: $(function() { var availableTags = [ "ActionScript", "AppleScript", "Asp", "BASIC", "C", "C+ ...

Checking for multiple click events in jQuery

To access the complete code, visit the GitHub Pages link provided below: Link This is how the HTML code appears: <ul class="deck"> <li class="card"> <i class="fa fa-diamond"></i> </li> ...

Limiting the x-axis drag function in a grouped bar chart using D3.js

For those interested, here is the link to view the code snippet: http://jsfiddle.net/4tqn7162/1/. When dragging the bars left or right causing the width of svg plot to disappear, I am looking for a solution that can restrict this behavior without impacting ...

The ng-repeat directive doesn't render any content on the page

Check out this code snippet HTML <div ng-controller="moveController as vm"> <div ng-repeat="move in vm.moves"> Move of the Week: <br /> {{move}} </div> JavaScript function retrieveMovesForCurrentWeek() { service.f ...

Alert: A notification appears when executing Karma on grunt stating that 'The API interface has been updated'

While executing karma from a grunt task, I encountered the following warning: Running "karma:unit" (karma) task Warning: The api interface has changed. Please use server = new Server(config, [done]) server.start() instead. Use --force to continue. A ...

Facing delays in receiving responses for inner loop in node.js

Having an issue with retrieving data from the inner loop, as there is a delay in getting it. In my code, I am fetching the user list along with their ancestors from the SQL table. The ancestors are needed to verify their root values in the hierarchy/tree ...

Locate the word or phrase without a comma

I am currently working on a code that involves finding keys with string values separated by commas. var db = { "name": "Nkosana", "middle": "Baryy", "surname": "walked", "batch_number": "test,b", "temp": ",,67,6,87,86,5,67865,876,67" ...

Adding a Fictitious Pair to a JavaScript Object Literal

When I work with object literals in JavaScript, I often encounter syntax errors when adding a new label / value pair without including the trailing comma. This can be frustrating as it's easy to forget to include the necessary delimiter. .draggable({ ...