@HostBinding in Angular 2 does not trigger change detection

When using @HostBinding in conjunction with Chrome's Drag and Drop API, the code looks like this:

@Directive({ selector: '[sortable-article]' })
export class SortableArticleComponent {

    @HostBinding('class.dragged-element')
    isDraggedArticle: boolean = false;

    constructor(elRef: ElementRef, private ref: ChangeDetectorRef, private appRef: ApplicationRef, private dndService: ArticleDndService) {
        this.el = elRef.nativeElement;
        Observable.fromEvent(this.el, 'dragstart').subscribe(e => this.onDragStart(<DragEvent> e));
        Observable.fromEvent(this.el, 'drop').subscribe(e => this.onDrop(<DragEvent> e));
    }

    onDragStart(event: DragEvent) {
        this.isDraggedArticle = true;
    }

    onDrop(event: DragEvent) {
        event.preventDefault();
        this.isDraggedArticle = false;
    }
}

However, there seems to be an issue where the isDraggedArticle class is not always removed from the element. Attempts were made by adding

this.ref.detectChanges();
this.appRef.tick();

to the onDrop method (where ref represents a ChangeDetectorRef and appRef represents an ApplicationRef), but unfortunately, it did not resolve the problem.

Answer №1

I believe I have discovered the resolution to the issue at hand: The drop event is not triggered on the dragged item, but rather on the item that it is dropped onto. As a result, instead of setting this.isDraggedArticle = false in the drop callback, it should be done in the dragend callback:

@Directive({ selector: '[sortable-article]' })
export class SortableArticleComponent {

    @HostBinding('class.dragged-element')
    isDraggedArticle: boolean = false;

    constructor(elRef: ElementRef, private ref: ChangeDetectorRef, private appRef: ApplicationRef, private dndService: ArticleDndService) {
        this.el = elRef.nativeElement;
        Observable.fromEvent(this.el, 'dragstart').subscribe(e => this.onDragStart(<DragEvent> e));
        Observable.fromEvent(this.el, 'dragend').subscribe(e => this.onDragEnd(<DragEvent> e));
    }

    onDragStart(event: DragEvent) {
        this.isDraggedArticle = true;
    }

    onDragEnd(event: DragEvent) {
        this.isDraggedArticle = false;
    }
}

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

Unlocking the Power of Select Options in Vue.js

I am currently learning how to use Vue.js. Below is an example of the Javascript code I have written: new Vue({ el: '#app', data: { classes: [] }, created: function () { var vm = this // Fetch API ...

What is the process of creating a global variable in Node.js?

My task involves calling an API that will return a JSON object stored in a variable. I need to print part of this JSON object on the console. However, I am facing an issue where I can't load the data to the console outside of the request{} loop. How c ...

Building a personalized payment experience using Python Flask and Stripe Checkout

I'm attempting to set up a customized checkout integration with Stripe on my Flask web application and I've encountered some issues. After copying the code from the Stripe documentation (located at https://stripe.com/docs/checkout#integration-cu ...

Unable to redirect page in Codeigniter after submitting button

I am facing an issue with inserting and updating data in my database using Ajax to my controller. Despite the data being inserted and updated accurately after clicking the button, the changes are not reflected on my view page until I manually refresh it. A ...

OpenLayers' circular frames surrounding the icons

I am currently using openlayers and trying to implement a feature that creates a circle around the icons on the map. I have been referring to this example on Stack Overflow but unable to draw the circle successfully. Can someone please assist me with this? ...

What could be causing the 405 error in my post request?

While attempting to send a post request to Firebase through my Vue app, I keep encountering an error illustrated in this image. I have a webpack server running and the website is on localhost:8080. However, I also have a live version hosted on hostinger a ...

Moving the words from textArea to each 'ol' element using JavaScript

When a word is entered in the textarea, it should be assigned to a specific class within an 'ol' tag. Each subsequent word will be placed in the next class sequentially. If there are no more words, the remaining classes should remain empty. <! ...

When you click on the text, the calendar will pop up for you to

When the text "SetExpiryDate" is clicked, a date picker opens. After selecting a date, the text changes to "Expires ${date}" where the selected date is inserted. If no date is selected, the text remains as it is. I'm curious how I can implement this ...

Preload-webpack-plugin does not support pre-fetching files

I have a query about prefetching and preloading content. In my vue app, I noticed that after building, I have duplicate files loaded in my dist/index.html file. Here is an example: Additionally, the "scripts" are not being preloaded/prefetched as expec ...

AngularJS is known for its ability to handle invalid HTML inserts

I am currently working on an app that relies on piecing together HTML from various APIs. Although we have attempted to move away from this approach multiple times, it always seems like the best solution in the end. While it may work well for now, I hope to ...

The parseJSON function is not compatible with AJAX requests

I am attempting to use ajax and retrieve JSON data in WordPress. Here is my Ajax code: $.ajax({ type: "POST", dataType : 'html', url: "/wp-content/themes/myproject/ajax/otros_alojamientos.php", da ...

Tips for Preserving the HTML Page State After Making jQuery Changes

Hi there! I am currently working on developing a card game using HTML5, CSS3, and Javascript. This game will communicate with a server built on node.js, facilitated by socket.io for data transmission. One of the key features I am trying to implement is th ...

"Allow users to select only the year with Material-UI DatePicker

Is there a method to display solely years using the Material UI DatePicker component in React? I would like to enable users to choose only the year, excluding months or days. Please note that neither the openToYearSelection option nor the autoOk feature ...

One important rule to remember when using React Hooks is that they must be called consistently and in the correct order in each render of the component. It

Encountering an issue while trying to use the ternary operator to determine which React Hook to utilize. The error message states: "React Hook "useIsolationDynamicPhase" is called conditionally. React Hooks must be invoked in the same order during every co ...

Enhance security in AngularJS by enabling data sharing between controllers and implementing callback functions for authentication

Currently, I am engaged in building an Angular front-end application, aiming to keep things simple without relying on tools like breeze or restangular while still maintaining code integrity. However, I have noticed that my code tends to become overly compl ...

What is the process for adding content to a JSON object?

I may have a simple question, but I'm new to backend development and I'm trying to figure out how to post in JSON format. Here is the JSON schema I am working with: email: { type: String, unique: true, lowercase: true, required ...

Ensure that dynamic functions are accurately typed within a proxy utilizing TypeScript

I am currently working on a unique function that utilizes a Proxy with a get trap to extract functions from multiple objects. The challenge I am facing is getting TypeScript to recognize these functions at compile time so that I can add them to my interfac ...

Integrating a Google map into an Ionic Side-Menu application

I am trying to incorporate a Google map into my Ionic app. I followed the code provided in this https://developers.google.com/maps/documentation/javascript/adding-a-google-map and it worked fine in Angular, but not in my side-menu Ionic project. The specif ...

The attempt to register a ServiceWorker for the angular scope was unsuccessful

I have encountered various solutions to this issue, some of which are not suitable for Angular and others simply do not work. In my quest to implement the "add to Homescreen" feature, I came across a helpful blog post (https://blog.betapage.co/how-to-add ...

How can I extract data from [Object object] in Node.js?

Can someone help me figure out how to extract data from [Object object]? Let's consider the following scenario for clarity. // Fetching data using dirty method var info = database.get('/htmltest') // Contents of test.db file {"key":"foo", ...