I'm running into an issue with two way binding in angular on a custom directive. I have a directive that will have a editor mode (and have different types of inputs) and display mode.
unfortunately, it seems that if there is a ng-switch the two-way binding breaks from the control. But the variables remain linked if I access it from an external component. Here is a very cutdown example plunker to show the problem.
http://plnkr.co/edit/M8gPfRlrVIXHdXREN1ai
If you modify the top input the changes propogate to the bottom input. But if you modify the bottom input the binding breaks.
How can I resolve this issue so that the changes to ng-model in the directive propagate to the controllers scope?
You are facing this problem because Ng-Switch creates its own scope
So there are two solutions to this problem
1) Use two dots in model
http://plnkr.co/edit/E7cE37VfrqatiMX885ZZ?p=preview
2) Use $parent in the model
http://plnkr.co/edit/eaFYF5kgOnkhsGpdgzFA?p=preview
Related
I have two directives that should both use isolate scopes, <outer-box> and <flag>. When I click on the <flag> directive, I want to change the background color of the other directive. Before importing my code into JSFiddle, I also had it working so that by default, a placeholder image appears in the flag directive, but once you click on that image, the country flag appears instead.
Can someone help with the styling a separate directive on ng-click?
Here's my code: https://jsfiddle.net/nLduw6xw/
(My countries data isn't working in JSFiddle for some reason)
You can do it with requiring one directive from another.
In this example you can require outer-box to be a parent of flag.
With this you have the access to required directive controller ( 4th parameter in link function), so you can call a method to set class on element.
Working JSFiddle : https://jsfiddle.net/2atnxhgy/
I'm currently working on a new custom directive which will transclude some HTML around the element you've called it on. This means however that if you have a ng-show directive as well on the element that the HTML would still be transcluded and hence shown.
A working example of the directive is located on this Plunk.
I'd like to counter this, by making my custom directive respond to ng-show but I can see a big problem with this approach as ng-show will hide or show the whole element it is called on.
On the other hand, I don't really like having a lot of custom directives each defining their own visible properties as an alternative to ng-show.
A third option would be to support both? This would allow me to switch of specific directives on an element as well as hiding it completely with ng-show
Has anyone got good recommendations on which approach I would have to take here? This is not a solitary case, we have a lot of custom directives of which we'll need to control visibility.
To summarize, these are the three options I'm thinking of:
Let custom directive respond to ng-show
Define own visibility control per custom directive (which could use ng-show underlying)
Support option 1 and 3
Any insights greatly appreciated.
I'm creating a font picker directive with angularjs for an Umbraco property editor.
In the directive I have a select with the fonts, which is bound to the isolated scope.
If I have two directives on the same page, and I change the selected font in one of them, the other one changes too.
How come? and how do i fix it?
hmmm...figured it out
when i initialized my scope i used the same json string on both variables that was used for binding the directives. Apparently the two scope variables were the same...
not my proudest day...
I'm in need of some pointers in my landingPage-builder project. (i'm currently stuck!).
The main issue is as follows:
Each element in the template (like the h1 and the paragraph) has attached a directive. What I need to get the directive to do is: create a template of HTML with some other directives attached like ng-click, ng-options etc, keep the bindings to the model intact (currently far away from working), update the model when changed.
I'm not trying to append to, or replace the element the directive is on, but make a html-template and inserting it into the DOM (almost like another view) so that the model on the left can be updated from the "settings" box on the right.
The project can be viewed here: http://193.107.29.196/~stian123/landingPageV3/app/#/pagebuilder/2
You may need Allow-Control-Allow-Origin for Chrome: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi/related
I'm a bit confused about $compile and doesn't really know when I need to use this part of the directives api.
Any suggestions?
Thank you!
If I understood your question correctly, you want to dynamically create templates, some of which have Angular attributes in them, then attach them to the DOM.
First, to (hopefully) answer your question, about when to call $compile:
Whenever you load in HTML from outside Angular's template system (like trying to set $(element).html(myHtmlString)), you need to let Angular compile it before you attach it to the DOM. In other words:
elem.append($compile(yourHTMLString)(scope));
This lets Angular traverse the DOM and parse any directives and bindings and attach them to the provided scope. If you don't $compile, Angular has no idea about those intended bindings at all, the HTML is never read by Angular.
Second, I don't know how flexible you want your templates to be, but if they're relatively fixed, but with some fixed customizable options (text, color, font-size etc), you might be better off creating a directive for each 'view', with the view options bound to the scope of the directive. Then you can just change the fields on the scope of the directive in the panel on the right side, and the view will update directly. You wouldn't even have to use $compile in this case.
If you want the user to be able to manually add the template HTML code, you will have to compile the HTML as described above.
I'm trying to build web app that dynamically load interfaces, using angularJS.
I found that it was possible to bootstrap some portions of my code after the initial bootstrap of Angular (HTML template + Controller).
My problem is that, doing so, the 2-way data-binding doesn't work. See for yourself:
http://plnkr.co/edit/MtAWP6
Any idea? Am I seeking for something to do the wrong way?
Thanks!
Your problem isn't a bootstraping one (although you really shouldn't be using bootstrap to instantiate a controller, but rather $compile, imo - see this answer). It is a scope problem. You define a "mymodel" model in your controller, but then define it again in your form, for which angular automatically creates it's own scope. While the form's scope inherits from the parent scope, and thus seems to be "binding" the model, the inverse doesn't happen.
You need to either establish a binding between both scopes (or $watch the form's variable, or define the for in the surronding controller), or just assign the controller you want to the form, directly.
See your problem exposed here (see that while your $timeout changes both models, manually setting the model only changes one)
See it resolved here (by basically assigning your controller to the generated form, rather than to a enclosing div of said form)
I think maybe you should take another look at routing/ deep linking. You should be able to specify both a template url and a controller.
Check out this video
And the api docs