I have a popup in my application that is hidden when page is loaded and it appears only on click on a specific button.
I have the following code inside my popup DOM
<a ng-click="settings();">welcome</a>
The same code works when i have it in my DOM that is visible when the page loads. But inside the popup, it does not work. It never goes inside the settings() function. Can anyone help me with this?
You should probably create a directive for it. See the documentation and this example. Notice that a scope is applied to the return value of the compilation, effectively var compiled=$compile(element.contents()); compiled($scope);.
Note that there is already a built-in include directive in Angular which might do what you want. The example there responds to changes in a drop down, though you could easily adjust it to respond to a click event.
Related
I have a classic dropdown menu on an Angular project with a main link always shown and a tree of sublinks shown only when hovering this one.
I have two events on the parent:
ng-mouseenter="vm.toggleDropdown($event)"
ng-mouseleave="vm.hideDropdowns($event)"
And they work perfectly fine. The main link has a simple:
ng-click="vm.navToState(item.urlState, $event)"
With a $state.go within to go to the string passed as parameter. On mobile devices, ng-mouseenter is being triggered on tap, showing the dropdown menu and this is perfect. The thing is that ng-click is being triggered too so the menu is only visible a fraction of a second before the next state loads. Is there any way to detect if ng-click is being fired by a touch event so I could add an if statement to navToState() and prevent the $state.go()? I understand that this way that main link would be unreachable in mobile but I'll take care of that adding an extra link within the dropdown.
Any other workaround for the same result is fine too.
Thanks!
Could you set a variable based on whether it is a mobile browser and use that as a check navToStart as to whether you state change or not, then have a separate state change function that doesn't care whether it's mobile or not so you can still change states in the mobile browser? That's one idea, but if it doesn't work, could be worth putting some code in your question for a reference.
Here's an answer on detecting mobile browsers:
https://stackoverflow.com/a/11381730/5349719
I have a very simple code snipper in my page where I have a span. Hovering over this span displays a popover for which I am using angular-ui-bootstrap.
<span uib-popover="This is a popover from Akhilesh"
ng-mouseenter="vm.logToConsole('I am trying hard...')"
popover-trigger="mouseenter">Hover over me to see a popup..!!</span>
Basically I have written a function which makes and API call when the user hovers over this span. The problem here is that let's say I have 10 span tags one below the other and the user quickly moves from 1st span to 10th span (in the process hovering over all 8 spans in between), the API call will get triggered for all the spans. This is what I do not intend to have.
Any idea how can I implement the debounce functionality here?
Use a delay, like one second, after the mouse enters the region, then if the mouse hasn't entered another area, make the API call.
The popover-is-open attribute was added under the 0.13.4 release that can be used to watch the state of your popover like so:
<span uib-popover="This is a popover from Akhilesh"
popover-is-open="vm.isOpen"
popover-trigger="mouseenter">Hover over me to see a popup..!!</span>
Then in your controller:
$scope.$watch('isOpen', function() { });
But if you are just trying to keep the popovers from opening so quickly, consider using the popover-open-delay attribute.
Depending on your use, I found the best method is to simply add ng-mouseover, ng-click etc to the element and define a function to be called.
You can even create a variable and attach it to that objects scope on the fly to keep track of the state (open close).
Kind of hacky, but there is currently no way to define a function that is called on open and on close within ui-bootstrap popover.
Ok, so I'll just start off saying I'm almost certain this bug is either arising from my lack of understanding of isolate scoping in angular directives or some weird interaction between directives and the angular google maps markers directive.
Anyways, the issue is that I have an instance of the angular-google-maps stuff in my main controller, and I have a tag within that. I also have a directive which is captures user inputs and uses them to populate a list in the main controller for the tag to do its thing. I pass in an object and function from the main controller into the directive's isolate scope.
The weird thing is that within my directives, I have bound this function onto a button click for a form, and for some reason, it takes 2 clicks to get the marker to appear. The function fires the first click, it has all the right values and everything, but the marker doesn't appear. Another weird I checked was simply calling the method twice in a row for one click which didn't work (still required 2 button presses).
The function modifies the array in the main controller (I have a feeling this is the root of the issue) which is used by the tag as a list of markers. Any ideas on why this could be happening? If it doesn't seem like an obvious misunderstanding of Angular scoping, I can post code.
My first thought is your data is happening outside of the digest loop. And if that's the case then adding a $scope.$digest() after your data is updated might solve it (or give you a console error).
I have the following example.
Two kendo UI buttons and two regular buttons. Both should enable/disable the button on bottom. Only the regular buttons do and I don't understand why. Probably has something to do with the scope...
EDIT:
From another example I have, it seems like the scope is updated correctly but the ui is not updated. In my example i have another control that when I click it the ui is suddenly being updated.
Found the answer:
When clicking the kendo button the scope does change but it doesn't go through angular so angular doesn't know that the scope was changed so the digest cycle doesn't run.
So adding $scope.$apply(); at the end of the function triggers the digest.
Took the explanation from here.
I am using a directive "slideable" which creates a slideout area and has a toggle. This code that was not written by me but it demonstrates a larger issue for me. When I changing views (most commonly /user/:id type), slideable is a directive used on the template. The directive searches for an element during its link function and binds a click event. The issue is that when I am changing routes and the new view ( same type but different id ) is being loaded the directive is re-binding to the old view. If I stop the browser in chrome during the link then I will see two ng-views on the dom and the issue is it binds to the one that is leaving.
I also have other issues that appear to be related to this phenomenon. Is it normal that the old view would still be on the dom while the new view is being formulated?? Why wouldnt the old-view be destroyed before the new one is rendered? How do I get around this issue in a directive like this?
Thanks.
I am looking to understand conceptually what is happening. I already modified the directive to select the latest view and to appropriately search and bind to the correct element. But I am a bit perplexed as to why there would be a state where both co-exist on the dom.
One definitive reason why the old HTML fragment is briefly present along with the new one is to support animation of transitions from the old to the new. Take a look at the ngView documentation and you'll see an example of an animated transition, and it'll be clear that this is not a bug or a design flaw.
Usually when someone has problems with binding to the right element or element's event, it's because they are selecting the element without limiting the scope of the selector to the HTML fragment being added or updated, or trying to target parts of the DOM outside of the directive. So that's the first place to check, that the directive is doing things right, but like I said we'll need code to check on that.