Enforce the splicing of the ng-repeat array with the utilization of track by

Our app incorporates a task list that can potentially grow to a substantial size. The main task list is accompanied by a sidebar, where selected tasks can be edited using a different controller (TasksSidebarCtrl instead of TasksCtrl which handles the list display). The selected task is duplicated and then merged back into the list, with communication managed through TasksService.

The significant number of watchers per task in the index prompted us to explore alternative solutions.

Implementing one-time binding has successfully reduced the number of watchers (currently only the submenu for editing/changing task statuses without selecting in the sidebar generates watchers). However, due to our use of track by task.id (which we deem necessary given the numerous filters and frequent DOM changes), employing splice does not effectively remove and replace the task with the updated version - defeating the purpose of track by.

Is there a method to enforce the update of this task item while still utilizing both track by and one-time binding?

tasks-index.html (filters omitted for clarity)

<md-list-item my-task-directive ng-repeat="task in TasksCtrl.tasks track by task.id">

TasksCtrl

TasksService.index().then(function(tasks) {
    vm.tasks = tasks.data ? tasks.data : [];   
});

$scope.$on('task-updated', function() {
    var newTask = TasksService.getUpdatedTask();
    $timeout(function() {
        vm.tasks.splice(newTask.index, 1, newTask.task);
    });
});

TaskSidebarCtrl

$scope.$watch(function() {
    return TasksService.getSelectedTask();
}, function (newVal, oldVal) {

    if (newVal !== oldVal) {
        /* Using copy here to prevent index view from updating during editing */
        vm.selectedTask = angular.copy(newVal);
        vm.index = TasksService.getSelectedTaskIndex();

    }
});

TasksService.update(vm.selectedTask).then(function(data) {
    // handle notifications etc., then...
    TasksService.updateTaskInIndex(vm.index, data.data);
});

TasksService

var selectedTask = {};
var indexOfTask;
var updatedTask = {};
var updatedIndex;

this.setSelectedTask = function(task, index) {
    selectedTask = task;
    indexOfTask = index;
};
this.getSelectedTask = function() {
    return selectedTask;
};
this.getSelectedTaskIndex = function() {
    return indexOfTask;
};
this.getUpdatedTask = function() {
        return {
            'index': updatedIndex,
            'task': updatedTask
        };
};
this.updateTaskInIndex = function(index, task) {
    updatedTask = task;
    updatedIndex = index;
    $rootScope.$broadcast('task-updated');
};

Using a basic angular.copy (with destination) instead of TasksService.updateTaskInIndex(vm.index, data.data) in TaskSidebarCtrl's update function results in the one-time bound properties not being updated in the index view due to the one-time binding constraint. While this approach functions without track by task.id, we are reluctant to make such compromises if feasible, and wish to maintain the use of one-time binding.

Is there a workaround?

Answer №1

When the track by task.id remains the same for an updated task, the DOM elements will not be rebuilt and existing expressions in that element will not update due to one-time binding.

To ensure that the old task's node is removed and a new one is inserted with updated expressions evaluated, use a track by expression that changes when the entry is updated. One way to achieve this is by assigning a tracking_id property to the task with a format of "{id}_{version}", where the version changes with each update. Then, utilize track by task.tracking_id.

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

Encountering a difficulty in sending data to the server through ajax with Cordova

I am currently working on a Phonegap Cordova project and I'm trying to send data to the server using AJAX but I'm encountering an error. Here is an example of my code: $(document).ready(function() { $('#frm').submit(function() ...

Select the send all text option when making a request

Using ajax, I can dynamically fill a drop-down select menu. My next step is to include all the text from the selected options in my request. <select name=".." > <option value="0"> ... </option> <option value="1"> xxx </option ...

Attempting to retrieve information from my MongoDB database and populate it into a <table> structure on a web page

My objective is to extract data from a MongoDB database and display it in an HTML table. Specifically, I am trying to retrieve information from the hangman database's players collection, which contains fields for name and score. Can anyone help me ide ...

Exploring the capabilities of AngularJS for efficient testing using Jasmine alongside mixpanel integration

Within my AngularJS application, I implement MixPanel for analytics by using the asynchronous script in my index.html file. index.html <script type="text/javascript">(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;a=e.createElement("script ...

Creating a Custom "Save As" Dialog in HTML5 and JavaScript for Downloading Files

I have developed a NodeJS/Express application that is capable of generating and downloading an Excel document (created using ExcelJS) when a user clicks on a button. Currently, the file gets automatically downloaded to the default download location of the ...

Interact with the horizontal click and drag scroller to navigate through various sections effortlessly, each designed to assist you

Currently, I am facing an issue with my horizontal scrolling feature in JavaScript. It works perfectly for one specific section that has a particular classname, but it fails to replicate the same effects for other sections that share the same classname. ...

What is the most efficient way to apply a class to the post div every 4 seconds using jQuery?

What is the most effective method to dynamically add a class to each div element with a class of "post" every 4 seconds using jQuery? <div class="34 post"> <img width="311" height="417" src="#" class="#" alt="newspapers" /> <h2><a hre ...

Mastering the Art of Scrolling Down Content with Button Click in Ionic 3

I'm currently developing an Ionic chat application and I need the content to automatically scroll down when the user clicks on the send text button. You can see a visual representation of this in the images linked below. https://i.stack.imgur.com/gwR ...

Implementing Vuejs sorting feature post rendering

Currently, I have elements linked to @click event listeners. <th @click="sort('dateadded')" class="created_at">Date Added I am looking for a way to automatically trigger this sorting function when the Vue.js component renders, so that th ...

Is there a way to establish communication between two ReactJS components by utilizing Jotai?

I am facing a problem with 2 reactjs files: Reports.js (handles report requests and displays results) AuthContext.js (maintains communication with backend server through a socket connection) The user initially visits the report page generated by Reports. ...

Is it possible to utilize Angular JS without utilizing a terminal interface?

Every time I try to work with the terminal, git, and other tools, my learning curve goes through the roof as I attempt to build an app quickly using CodeIgniter. I understand the importance of a JavaScript framework like AngularJS - is there a way to avo ...

The consistency of values remains constant throughout all Ajax requests

I am presenting the code snippet below: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8> <title>Document</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" ...

What is the best way to pass values between JSP Expression Language and Javascript?

I have a request object with the following content: List<Integer> list What is the best way to loop through this list using JavaScript? I am interested in obtaining the values of each element within the list. Note that these list values are not cu ...

Looking to Identify a Click Within a Complicated Component and Retrieve the Component's ID

Currently, I am working with React for development and have a need to capture clicks at the topmost parent level for performance reasons. const clickHandler = (e) => { console.log("clickHandler", e.target) --> I want to identify the child ...

What is the best way to keep a header row in place while scrolling?

I am looking to keep the "top" row of the header fixed or stuck during page scrolling, while excluding the middle and bottom rows. I have already created a separate class for the top row in my header code: view image description ...

JavaScript - Sort an array containing mixed data types into separate arrays based on data

If I have an array such as a=[1,3,4,{roll:3},7,8,{roll:2},9], how can I split it into two arrays with the following elements: b=[1,3,4,7,8,9] c=[{roll:3},{roll:2}]. What is the best way to separate the contents of the array? ...

Getting the input from an HTML editor and inserting it into a textarea using JavaScript

Currently, I am in the process of developing an HTML editor for a project. I have downloaded a program online that I am attempting to customize according to my requirements. However, I am encountering difficulties when trying to retrieve the inner HTML of ...

Navigating through Angular JS validation procedures step by step

I have a wizard in angular js consisting of multiple steps: <wizard on-before-step-change="log(event)" on-step-changing="log(event)" on-after-step-change="log(event)" user="user"> <step title="step 1"> </step> <step title="step 2"& ...

Adding HTML content to routes in ExpressOrEnhancing routes

Recently, I've been working with a basic index.html file. My goal is to have the routes file append an HTML button when requested by the browser without actually modifying the original file. This may seem like a peculiar idea, but my intention is to c ...

Understanding which page is being rendered through _app.js in React/Next.js is crucial for seamless navigation and

Currently, I am working on rendering my web navigation and footer on my _app.js file. My goal is to dynamically adjust the style of the navigation and footer based on the specific page being accessed. Initially, I considered placing the navigation and foot ...