Trouble with Displaying Angular Template using ng-hide

I am encountering an issue with my angular directive that is used to display a button form. The template remains hidden until it needs to be displayed for the user. Although the template works fine on its own, it does not appear when integrated into the larger form.

Below is the directive code:

.directive('buttonToggle', function() {
                return {
                    restrict: 'A',
                    scope: {
                        myBtnArr: "="
                    },
                    template: '<button ng-click="click()">{{ myBtnTxt[myBtnArr] }}</button>',
                    link: function(scope) {
                        scope.myBtnTxt = ["AND", "OR", "NOT"];
                        scope.click = function() {
                            scope.myBtnArr = (scope.myBtnArr < 2 ? scope.myBtnArr + 1 : 0);
                        }
                    }
                };
            });

The html snippet that functions correctly is as follows:

<div button-toggle my-btn-arr=0></div>

However, the following html snippet fails to work properly:

<tr ng-show="rowsShown >= 2"><td>Search by:</td><td><div button-toggle my-btn-arr=0></div><select ng-model="selection2" ng-options="option.text for option in options"></select><input type="text" size="20" ng-model="queryF2"><ng-md-icon icon="add_circle_outline" style="fill:#a9a9a9" ng-click="addSearchField();"></ng-md-icon> <ng-md-icon icon="remove_circle_outline" style="fill:#a9a9a9" ng-click="removeSearchField();"></ng-md-icon></td></tr>

When this html snippet is executed within the larger partial controlled by an unrelated controller, an error occurs:

Error: [$compile:nonassign] Expression '0' used with directive 'buttonToggle' is non-assignable!

I attempted to resolve the issue by using scope.$apply, but encountered another error:

Error: [$rootScope:inprog] $apply already in progress

It seems like I need to correct how the scope is wrapped, but I'm unsure of the solution. Any suggestions?

Answer №1

If you're hesitant about establishing a two-way binding for my-btn-arr, consider opting to merely transmit data to the directive rather than binding it to an existing variable. In this case, refer to the attribute argument of link.

.directive('buttonToggle', function() {
    return {
      restrict: 'A',
      scope: {},
      template: '<button ng-click="click()">{{ myBtnTxt[myBtnArr] }</button>',
      link: function(scope, elem, attr) {
        scope.myBtnArr = attr.myBtnArr;
        scope.myBtnTxt = ["AND", "OR", "NOT"];
        scope.click = function() {
          scope.myBtnArr = (scope.myBtnArr < 2 ? scope.myBtnArr + 1 : 0);
        }
      }
    }
  });

If you wish to include the option of passing a variable as input, implement $parse.

// To make it work with an isolated scope, inherit from the parent scope
scope : true, 
link: function(scope, elem, attr) {
  // Evaluate the expression against the scope
  scope.myBtnArr = $parse(attr.myBtnArr)(scope);
}

You can now utilize the directive like so:

 <div button-toggle my-btn-arr="0"></div>
 <div button-toggle my-btn-arr="view.myValue"></div>

If your aim is truly to have a two-way binding, ensure that writing values back into the path defined with the expression my-btn-arr is feasible. By using scope: { myBtnArr: "=" }, you must utilize the directive with a writable expression, as shown below:

 <div button-toggle my-btn-arr="view.myValue"></div>
 <!-- Cannot assign "0"-->
 <div button-toggle my-btn-arr="0"></div>

Check out some examples here: http://jsfiddle.net/Lw7ckt9x/1/

Answer №2

Instead of relying on the link function, consider accomplishing the same task within the controller function. The use of the link function becomes necessary only when DOM manipulation is involved; otherwise, the controller should suffice for your requirements.

Answer №3

Take a look at this issue highlighted in the ngdocs.

The problem arises when you use:

<div button-toggle my-btn-arr=0></div>

where 0 is not something that can be assigned. Essentially, you cannot write 0 = 1;

To resolve this issue, you need to pass a variable with the value of 0 instead of simply using 0 For example:

<div button-toggle my-btn-arr="obj.myvar"></div>

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

Tips for implementing and utilizing an optional parameter within Vue Router

I am trying to set up a route for a specific component that can be accessed in two ways - one with a parameter and one without. I have been looking into optional parameters but haven't found much information. Here is my current route setup: { pa ...

Is it mandatory for the npm install command to only be compatible with Node.js for the script

I've encountered an API that provides a JS SDK, and the instructions on its GitHub page suggest using npm install. My question is whether I need to have Node.js in order to use this SDK since it seems to be designed for it, or if I can simply work wit ...

Implementing an automatic link generation feature for files within a directory using JavaScript

I could really use some assistance with this. I created a YouTube example, which can be viewed in this PLNKR LINK: http://plnkr.co/edit/44EQKSjP3Gl566wczKL6?p=preview In my folder named embed, I have files titled p9zdCra9gCE and QrMOu4GU3uU, as shown belo ...

What is the best way to incorporate a feature that flips all choices in react-select?

I'm working with a multi-option Select component from react-select, and I need to add a special option that will invert the selected options into unselected ones, and vice versa. When this 'Invert selection' option is chosen, I don't w ...

Learn how to securely transmit data using basic authentication in Node.js with the node-fetch module

Having trouble with this code. I am facing an issue where a "post" request with basic authentication returns a 200 status, but no response data is received. Surprisingly, when the same code is executed without auth credentials, it works perfectly fine. l ...

IE does not support hover effects

Having trouble with a hover effect that works in Chrome but not in MSIE. Are there any alternatives or fixes to make it work in MSIE? The hover/rollover effects I've tried all seem to have this issue in IE. normalize.css demo.css set2.css font- ...

Having trouble locating the name WebGLObject in my TypeScript code

Every time I try to run ng serve command An error pops up on my screen saying: "WebGLObject cannot be found." ...

AngularJS encountered a TypeError when trying to parse the object, indicating that it is not a

I've streamlined my app to the basics, but I keep encountering an error with $parse: TypeError: object is not a function What am I doing wrong? What piece of the puzzle am I missing? Interestingly, everything seems to be working fine in this plunker ...

Use angular-resource to add a new entry to the db.json file

I have a JSON file called db.json with the following structure: { "menu":[ { "id":0, "item":"item1" },{ "id":1, "item":"item2" },{ "id":2, "item":"item3" } ], "feedback":[] } Currently, I am using Angular's $resource to send a Jav ...

choosing a specific element with jQuery to be used for future purposes

I'm having some trouble with the following code snippet: var star = $("._container > favorite"); var symbol = $(star.parentNode.parentNode).attr("symbol"); var exchange = $(star.parentNode.parentNode).attr("exchange"); After running ...

Switching an element from li to div and vice versa using Jquery Drag and Drop

I am currently experimenting with the following: Stage 1: Making the element draggable from li to div upon dropping into #canvas Placing the draggable element inside #canvas Stage 2: Converting the draggable element from div back to li when dropped i ...

Using anti-cache code in jQuery's getJson function

During an interview, I was presented with the following question: Can you provide a one-liner code showing the proper syntax to add an anti-cache code to all jQuery getJson calls in a project without individually adding it to each call? I must admit th ...

Utilizing Vue.js to dynamically add a class through computed properties

As a beginner in Vue.js, I want to dynamically add or remove classes based on certain conditions. Specifically, I am trying to remove the success class when the total sum exceeds 25, but for some reason the color is not changing as expected. Can anyone p ...

The MaterialUI table pagination feature is experiencing an issue where the "Next" button is

Every time I attempt to search for a record with a lower value, such as 6, 14, 19, or 20, the Next button does not become active. However, when dealing with larger records, it functions perfectly fine. I am uncertain about what mistake I might be making. ...

Assign a variable the source of the web subsurface A-frame setting

I want to utilize the websurface A-frame component () to change the URL of the websurface when a button is clicked. I have defined a variable called source and I want the websurface URL to be updated to the value of this variable upon clicking the button. ...

What is the proper way to utilize JQuery and Ajax to communicate with a global function in writing?

My goal is to retrieve data from an AJAX request and store it in a global variable. Despite trying to make the call synchronous, I am encountering issues where the value of the global variable becomes undefined outside of the Ajax request. I have attempt ...

Implementing a callback function in Vue js 2 for handling dispatched actions within a component

Is there a method to determine if the action dispatched from a component has completed without utilizing state management? Currently, I have an action called createAddress. In my component, there is a modal where users input their address. Once the user en ...

Executing a component's method using HTML in Vue2

In my development project, there is a .vue file named ServiceList. This file imports the component called Information.vue. My objective is to execute the code from the Information component in a loop within the template of the ServiceList file. Here is an ...

How to incorporate a JavaScript class into a VueJS project

Looking to incorporate a JavaScript class into my Vue application. The class structure is as follows: class className { constructor() { ... } function1() { ... } static funtion2() { ... } } Attemptin ...

The event handler attached to the 'click' event will only be triggered upon the second click

After implementing the script, I noticed a strange behavior. When I click it on load, everything works perfectly. However, when I click it via a dynamically created element, the HTML seems to shift or stretch on the first click before returning to normal. ...