I want to do something similar to a $routeProvider .when but instead of using URL I would like to load an HTML file and a new controller based on a variable change.
Assume I use a $http polling and the poll has a variable that changes, and I would like to change the Controller and template based on that. What is the best strategy for this
I'm new to this so please excuse if this is a stupid question.
Thank you so much.
The first thing that comes to mind is you could do something like this
<div>
<directive1 ng-if="switch_var == val_1"></directive1>
<directive2 ng-if="switch_var == val_2"></directive2>
...
</div>
Create a directive for each template/controller combo you want, and then choose which directive to show based on your poll variable.
Alternative to using a bunch of ng-if's, use ng-switch - http://docs.angularjs.org/api/ng/directive/ngSwitch
Related
I have a need to use the same directive within a directive, depending on a conditional param. However, when ever i try to do it, it seems to go to an endless loop. As i understand, it tries to pre-load the templates and that causes an endless recursion and at the end, it just throws me the following error:"RangeError: Maximum call stack size exceeded".
I have created an example in fiddle.. as you can see in the example, when the param's value is "1", it creates the error (even when the second level param is valued as "2" so it shouldn't have real recursion issues in the controller/app).
https://jsfiddle.net/qh9nh1gx/
"custom-directive"'s template:
<div>
<div ng-if='info==1'><div custom-directive info='2'></div></div>
<div ng-if='info==2'>DONE,single.</div>
</div>
Thanks
I have found 2 options to deal with the issue, the first one, is exactly what Jju described - creating a new "compiler" method (it can be grabbed from the url he sent).
The second option - always using an additional template for the "recursive" parts of the directive. For example, in my directive, i had a "ng-repeat" part that depending on the items value, it could request to display the directive again. while i used "ng-include" to have the other directive, it worked.
<div ng-repeat="item in items" ng-include="'inline-possibly-recursive-template"'></div>
in that template, you can call the directive again without any issues..
I hope that it will anyone else that will stumble into that issue.
You can look into https://stackoverflow.com/a/19065910/1680674 that describe a common approach to create directive that use himself inside
if it's jquery, we can do like $('table-row').clone().preprenTo($('table'));
I know it's just push a new value into an object in adding new data but I want to first insert the empty row and field first, how to add that html with angularjs?
John added a link to a famous question/answer regarding AngularJS. I would advice you to read that.
That said, to answer your question - in angular you do not tell it how to manipulate the dom. You tell it what data you have and how you want it presented.
I can only guess to what you are trying to do, but if you have a template (your 'table-row') and a 'destination' ('table') you would describe it in AngularJS like this:
<table ng-controller="PersonsController">
<tr ng-repeat="person in persons">
<td>{{person.Name}}</td>
<td>{{person.Address}}</td>
</tr>
</table>
That is great, but how do you add a row? Well you don't "add a row" - you add a person and AngularJS will do the adding of rows for you. You already explained how you want a person displayed.
To add a person you would have to add a person to a list/array of persons and that list would be in the scope of your view/application.
persons.push({Name: 'Bill', Address: 'Somewhere'});
You will need to attach the persons to your scope, which you will do in a controller. A controller would have to be associated with the code above with the ng-controller directive.
app.controller('PersonsController', function ($scope) {
$scope.persons = [];
});
In the above code i assume you have a variable app pointing to your angular application. There is a small learning curve you will have to overcome, going from jquery to angular. Mostly, the way i see it, is moving your mindset from a imperative coding style to a declarative coding style.
I suspect you need a paradigm shift. Read "Thinking in AngularJS" if I have a jQuery background.
Then, if you still think that your problem is best solved by adding a row to the DOM, consider using an AngularJS directive.
I am working on a website based on angular js.
Currently, I have written about 5000 line code in angular js.
So I have to make some changes without touching my angular js.
I want something like this:
$(document).on('click','#buttonid',function(){
//performing some necessary task then call ng-click method
ngclickmethod();
});
HTML Code:
<a ng-click="ngclickmethod()" id="buttonid">
Please advise how can I achieve that.
Many Thanks
So it looks like you are trying to call an angular function outside of angular. Try this..
angular.element(document.getElementById('yourControllerElementID')).scope().ngclickmethod();
this will call the method you want. Be sure the controller element ID is the controller that contains the ngclickmethod function
I have some elements I want to only show the author of the document.
I can do something like this:
<div ui-show="currentUser == doc.user">Edit</div>
<div ui-show="currentUser == doc.user">Review</div>
Which is fine but because in my production code the ui-show is much longer than this example I don't want to copy and paste it everywhere that I need it.
I want to set a single variable that'll dynamically update as users log in and out or as the document gets updated with new / different users.
<div ui-show="isUser">Edit</div>
<div ui-show="isUser">Review</div>
I found that I could make isUser into a function.
<div ui-show="isUser()">Edit</div>
<div ui-show="isUser()">Review</div>
And write the conditions in the controller.
You have a couple of options to solve this problem:
1) Introduce a "global" or "parent" controller to your application. This will contain your isUser scope variable that you can basically set from any controller beneath this controller. Meaning that you can have a LogInController which will handle log off/in and can set that variable via $scope.isUser = false.
Here is a fiddle with an example of what this might look like: http://jsfiddle.net/digitalzebra/MrQrX/
2) Load different templates or includes based on whether or not the user is logged in/off. when using <ng-include src="partialTemplate"> the src attribute is actually an expression. So, you can toggle what template is actually loaded based on the value of that expression. You can then set the value in your controller and dynamically change which template is loaded: $scope.partialTemplate = "loggedOff.html"
I ran into this problem in several situations, but let's use one example here. Say I have an interaction flow of form submission. It is composed of three steps, for example, data input step, double checking step, and confirmation step. In each step, I will display different relevant information along with the form using ng-show/ng-hide. The way I do it now is to define the flow like a state machine and use a internal variable (e.g. currState) to represent the current state, and modify the variable when switching to a different state. In ng-show/ng-hide, I check the currState variable to show/hide the element. Something looks like this:
In my Angular controller:
$scope.currState = 'DATA_INPUT';
In my HTML:
<div ng-show="currState == 'DATA_INPUT'"></div>
I'm wondering if there is any native support for this kind of use case or best practices/patterns, since the way I'm doing now is error-prone and not very flexible. Thanks!
You can use ngSwitch for this:
http://docs.angularjs.org/api/ng.directive:ngSwitch
So:
<div ng-switch on="state">
<div ng-switch-default>Fist. <button ng-click="state='second'">Next</button></div>
<div ng-switch-when="second">Second. <button ng-click="state='final'">Next</button></div>
<div ng-switch-when="final">Final</div>
</div>