achieving bidirectional binding within a directive without using an isolated scope

One of my directives is set up like this:

angular.module('somemodule').directive('tooltipText', function ($timeout, $compile, $document, config, $filter) {
  return {
    restrict: 'A',

    scope:{
       tooltip: '='
     },
    link: function (scope, element, attrs) {
      let tipHtml = `<div ng-class="tipClass">
                      <div class="header">
                        <span>{{ title }}</span>
                      </div>
                      <div class="body">
                        <br ng-show="showDescription && description"/>
                        <span ng-show="showDescription">{{description}}</span>
                      </div>
                      <div class="tooltip-arrow"></div> 
                    </div>`;

    scope.$watch('tooltip',(changedAttr) => {

    if (element) {
      let elm = angular.element(element)[0];
      if (elm.getAttribute('tooltip-show')) {

        if (changedAttr && elm.offsetParent != null) {
          showtooltip(element);
          elm.scrollIntoView();

        }
      } else {
        element.bind('mouseover', showtooltip);
      }
    }
  });
 showtooltip = (elem)=>{
 //do some tooltip logic and then after a timeout of say, 5secs, I do

   scope$.tooltip = false;
   //i.e i remove the tooltip and set the attribute
   // value back so that next time change can be 
   // watched by this directive. Basically it's a tooltip
   //that should last for around 5 seconds and when
   //setting the attribute on element again to true,
   // it should reappear.
   }
});

However, there seems to be a conflict with other directives due to this isolated scope. How should I best address this issue?

Answer №1

To prevent the use of isolate scope, you can simply monitor the attribute:

scope: false,
link: function (scope, element, attrs) {
    let tipHtml = `<div ng-class="tipClass">
                  <div class="header">
                    <span>{{ title }}</span>
                  </div>
                  <div class="body">
                    <br ng-show="showDescription && description"/>
                    <span ng-show="showDescription">{{description}}</span>
                  </div>
                  <div class="tooltip-arrow"></div> 
                </div>`;

    scope.$watch(attrs.tooltip,(changedAttr) => {

During each digest cycle, the watcher will assess the attribute as an Angular Expression and execute the listening function with any new value.

For more details, refer to the AngularJS $watch API Reference.


that's fine. but i need to push the changes back to parent attribute. How will that work? so after say 10 seconds i need to do something like attrs.tooltip = false; And this is not a static value set like attrs.$set does. I need the actual binding..because otherwise after those 10 seconds the value would still be true and the tooltip won't be triggered again

Utilize the $parse service

function postLink(scope, elem, attrs) {
    var getter = $parse(attrs.tooltip);
    var setter = getter.assign;
    setter(scope,false);
};

If the attribute allows assignment, this action will change it to false within the scope context.

It is important to note that two-way binding introduces complexity in tracking data changes. The component owning the data should be responsible for modifying it. Input should be one-way, and outputs should be implemented through callbacks.

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

Scroll to make the div slide in from the bottom

I'm trying to achieve a similar effect like the one shown in this website (you need to scroll down a bit to see the divs sliding in). Although I'm not very proficient in JS, I was able to create a code that makes the divs fade in from 0 opacity ...

Encountering the "Component resolution failed" error in Vue 3 when using global components

When I declare my Vue components in the top level HTML file, everything works fine. Here is an example: <body> <div class='app' id='app'> <header-bar id='headerBar'></header-bar> ...

I have come across this building error, what do you think is the cause of it?

My attempt to launch my company's React.js project, downloaded from Tortoise SVN, is encountering an issue. PS C:\Projects\Old EHR> yarn start yarn run v1.22.19 $ next start ready - started server on 0.0.0.0:3000, url: http://localhost:30 ...

What sets React$Element apart from ReactElement?

Attempting to implement flow with ReactJS and needing to specify types for prop children. The article on Flow + React does not provide any information. Despite encountering examples using ReactElement (e.g), I received an error message from flow stating i ...

What is the best way to write an SQL query to safely insert a record into a table with a dynamic name?

I'm working on a function that can insert a record into a table in PostgreSQL. The catch is that the table name needs to be a parameter for the function, and the column names are determined dynamically. To ensure protection against SQL Injection, I am ...

Firefox Issue: SetTimeout Redirect Function Not Functioning Properly

Working on a page that redirects users to an installed application or a webpage as a fallback. This is implemented using ClientScript.RegisterStartupScript when the page loads, with a Javascript snippet like this: <script type='text/javascript&apo ...

What is the process for integrating TypeScript compiling into a JavaScript application?

My project includes a build.js file that is responsible for building the project. It has two main objectives: Compile .ts files and store them in a new directory. Create an asar archive containing the compiled files. Since typescript (or tsc) is availabl ...

What is the best way to show only a specific v-for element in Vue.js?

Is there a way to select a specific item from a v-for loop in vue js? I am using v-for to retrieve Youtube data API items. Each item contains an iframe that should only be displayed when a user clicks on a play button. Currently, all the iframes are shown ...

Utilize a dual-color gradient effect on separate words within the <li> element

I am attempting to display the fizz buzz function in an unordered list, with each word being a different color ('fizz'-- green, 'buzz'--blue) as shown here: I have successfully displayed "fizz" and "buzz" in their respective colors ind ...

challenges surrounding the use of getElementByTagName

Within my webpage, I have implemented two select elements, both containing multiple options. However, I am facing an issue where I can only access the options from the first select box using getElementByTagName("options"), and unable to retrieve the option ...

Error retrieving data from JSON

I'm attempting to extract a value from the JSON data retrieved via Ajax. Take a look at the example I'm working on here: http://jsfiddle.net/NNrcp/6/. jQuery.ajax({ url:"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.pla ...

Exploring every conceivable method for accessing a file from a distant server

I am striving to maximize the flexibility of my script, thus I am seeking all potential methods in PHP and JavaScript to access the content (and not the source code) of a PHP file from a remote server. I have come across CURL, fopen, and include for PHP ...

"Displaying a popup message prompting users to refresh the page after clicking

I need to implement a feature where the page refreshes only after the user clicks the "OK" button on a dialog box that appears once a process is completed. The issue I'm facing is that in my current code, the page refreshes immediately after the proc ...

Discover the steps for dynamically adding a new row in an Angular application

I am trying to add new rows to a table in Angular, but I'm having some trouble. Initially, there is one empty row, and when I click on the "add new" button after entering details, a new row should be added. I was able to do this using jQuery, but I&ap ...

Include chosen select option in Jquery form submission

Facing some challenges with a section of my code. Essentially, new elements are dynamically added to the page using .html() and ajax response. You can see an example of the added elements in the code. Since the elements were inserted into the page using . ...

What is causing this particular area to remain unaffected by the blur effect?

issue I followed a tutorial to create a mouse trailer from this video - https://www.youtube.com/watch?v=kySGqoU7X-s. However, when I tried adding text and other elements inside a div, the blur effect just didn't show up. I attempted using z-index but ...

I'm having trouble getting jquery css to function properly in my situation

I am trying to implement a fallback for the use of calc() in my CSS using jQuery CSS: width: calc(100% - 90px); However, when I tried running the code below, it seems like the second css() function is not executing. I suspect that there might be an issu ...

Using JavaScript to Access PHP Files

Would like to understand the process of calling a php file (test.php) from either "x:" or "y:" in the code below. var example1 = { x: ['giraffes', 'orangutans', 'monkeys'], y: [20, 14, 23], name: 'Most read', ...

A guide to implementing the map function on Objects in Stencil

Passing data to a stencil component in index.html <app-root data="{<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b5d4d7d6f5d2d8d4dcd99bd6dad8">[email protected]</a>, <a href="/cdn-cgi/l/email-pro ...

Controlling an AJAX request to fetch individuals

I am currently using an ajax request to display people data on the page, which is retrieved from a backend database. The search form on the page includes options for location, sector, service, and job title. Below is the javascript code being used: //var ...