I want to bind tag name to variable in AngularJs. Direct way doesn't work:
<div ng-app ng-init="list=['pre', 'div', 'em']">
Check the list: {{list}}
<div data-ng-repeat="item in list">
{{item}}: <{{item}}>content</{{item}}>
</div>
</div>
How to do it right?
You're going to want to make a Directive and use the $compile service module.
Angular template system works on DOM tree, not on strings, so template must be valid HTML and usage of {{}} for tagname is impossible. We can write own directive for it (see Max answer) or if here is small set of options it can be more easy to use ng-include and set of templates for options.
Related
I would like to save an object in a ngRepeat so that I can use that object in its children, like shown in this code:
<div ng-repeat="bar in foo.bar>
<div ng-repeat="qux in baz.qux" myvalue="{'item1':foo.var1, 'item2':qux.var2}">
<div ng-click="myFirstFunction(myvalue)"></div>
<div ng-click="mySecondFunction(myvalue)"></div>
</div
</div
The object I want to generate and then use is rather large and I'd rather not define it repeatedly for each ngClick directive.
I considered saving it into a scope variable but the object will change for each iteration of the ngRepeat.
Is there a directive or an other way that I can use to store this value for later use?
To avoid the repetition of what is probably a long variable definition, you can use the ngInit directive, whose content will be executed each time a corresponding element is created.
<div ng-repeat="bar in foo.bar>
<div
ng-repeat="qux in baz.qux"
ng-init="myValue = {'item1':foo.var1, 'item2':qux.var2 }"
>
<div ng-click="myFirstFunction(myValue)"></div>
<div ng-click="mySecondFunction(myValue)"></div>
</div>
</div>
However, a complex code in a template is rarely a good idea. Contemplate moving your logic inside a controller, as advised by the documentation:
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
You can just do the naive thing here and it'll work:
<div ng-repeat="bar in foo.bar>
<div ng-repeat="qux in baz.qux">
<div ng-click="myFirstFunction(foo, quz)"></div>
<div ng-click="mySecondFunction(foo, quz)"></div>
</div>
</div>
Angular will know the scope of the repeat when you click.
You could store it in local storage using ng-storage.
https://github.com/gsklee/ngStorage
This would allow you to store it, then use it anywhere in the application.
cookies, you also have ng-cookies
https://docs.angularjs.org/api/ngCookies
try this out! or cookieStorage
What easy way to insert html item to exists template HTML in angularjs?
For example there is template generated in PHP:
<div id="block">
<!-- Insert here template from Angularjs-->
<div class="item"></div>
<div class="item"></div>
</div>
I can Use Jquery like as:
$('#block').prepend('<div class="item"></div>');
How I can same in Angularjs?
You can use jquery to add HTML but you'll need to compile it first using
var compiledHTML = $compile(html)($scope);
and then pass it on to jquery's method
$('#block').prepend(compiledHTML);
But as #cerad mentioned definitely this is not the best way.
You should use angular's data binding, you can also treat is as a template engine.
eg:
your html code is this
<ul>
<li ng-repeat="msg in allMsgs">{{msg}}</li>
</ul>
your controller code is this
app.controller($scope){
$scope.allMsgs = [];
// i dont know socket.io well, so this part may not work :)
// and it's better to separate it to a service and use $rootScope.$apply()
soceket.on('msg',function(msg){
$scope.$apply(function(){
$scope.allMsgs.push(msg);
});
});
}
Note you need to use $apply in order to make the data binding work when data is
changed by events that angular doesn't control.
Some useful links
a blog about angular socket-io
$apply doc
I'm quite new to angular and frontend in general, but what i'd like to see is something similar to what routing with ngView gives, but without routing, i.e just load a template on some event. To be more specific, let's say i have an input field somewhere in the header and when i click/focus on this field a special panel with different input options shows up. The trick is that this input field and other elements are already a part of a template which is loaded into ngView, so as i understand i can't use another ngView for options pane.
use ngIf, ngShow, ngHide, ngSwitch for stuff like that
<button ng-click="showStuff = true">Show Stuff</button>
<button ng-click="showStuff = false">Hide Stuff</button>
<div ng-show="showStuff">Showing Stuff</div>
<div ng-hide="showStuff">Hiding Stuff</div>
Have a look at this plunker for a quick and dirty, working example.
Note that the showStuff variable is just magically created by angular on the root scope, since I'm not using a controller.
You can load templates with ng-if and ng-include like this example:
<body ng-app="app">
<div class='container'>
<button ng-click='tmpl = true' class='btn btn-info'>Load template!</button>
<div ng-if='tmpl'>
<div ng-include="'template.html'"></div>
</div>
</div>
</body>
The ngIf directive will add element to the DOM when the argument expression is true. Then, the angular will compile the inner directive ngInclude, loading the template.
I have a template which I want to use in many parts of my application.
The template contains select box with a model assigned.
I include the template by the means of ng-include.
<span ng-include="'templateWorking'" ng-init="selectModel=data.field"></span>
and then in template:
<script type="text/ng-template" id="templateWorking">
<select ng-model="selectModel">
<option value="Test1">Test1</option>
<option value="Test2">Test2</option>
</select>
Of course, it does not work since ng-include creates a new child scope.
It is possible to get it work when I use one model (using dot . in a model like data.model).
But how it is possible in this particular case so I can use this template with different models in different controllers?
Besides, I need to dynamically attach a handler to the select (e.g. ng-change="doSmth()").
Thanks in advance.
For the reference:
http://plnkr.co/edit/NiLQyVQGb6X1mA0sVvA1?p=preview
In this case it was best to use a directive instead. You can get some control over ng-include by using onload but if that's not enough, using a directive is your best bet.
Reference: Difference between onLoad and ng-init in angular
I have an html file with ng-includes inside
<div ng-controller="MapMenuCtrl">
<div class="mapMenu row">
<ng-include src="'partials/mapMenu/filterDropdown.html'"></ng-include>
<ng-include src="'partials/mapMenu/alertDropdown.html'"></ng-include>
<ng-include src="'partials/mapMenu/investigationDropdown.html'"></ng-include>
</div>
</div>
The problem is that I need MapMenuCtrl for each of ng-include. But when it is set as in example, it works, but only a half. For example in one of this files I use ng-model for one of $scope variables of MapMenuCtrl and it doesn't bind.
I was trying to set controller for each of ng-include, but it loads 3 times, though I need only 1.
I hope you understood me. I know, that my english is quite bad
ng-include creates a new scope. Put an object on the controller scope and put all bindable stuf inside.
You can call it model for example. Then the bindings should work as expected.
Here is a link for a details of the problem you face i believe:
Does my ng-model really need to have a dot to avoid child $scope problems?