I hope someone can help me with this problem, it really drives me crazy :P I have created a Plunker in order to illustrate the problem. See the Demo here http://plnkr.co/edit/BRlDgKYlE87Bh3t53tpZ?p=preview.
My code is in the plunker.
So my problem is that I'm not able to change my scope value in a different html view that I'm in. As the Plunker show, I have two buttons in index.html; button1 and button2. When I click on button1 I want scope.test to change to "button1", and when I click on button2 it should change to "button2", this value exists in index2.html. As you can see on the console.log message, that never happen. I use rootscope, but still I'm only able to change the value if the scope exists in the same html page and not in another. Please help!
What you have coded up is not a single page application, html2 has no idea about your angular code in app.js. You need to use routing and you should be using a service to share state between the two 'pages' or views in the case of angular routing
EDIT
Take a look at this plunkr
Here you will see angular routing in action and a service that can be shared between the two controllers. When switching between the two pages, the controllers they are attached to get destroyed, so going from Page 1 to Page 2 means that contollerA no longer exists, so you need to use the service to store the state of what was clicked on from Page 1.
Hope this makes sense!
Related
I am a bit of a beginner, but I would like to ask a general question. AngularJS does a watch on binded variables. My question is, when I navigate and a new html template is loaded, are the old watched values removed, or do they stay in the loop?
Hello $watch is bound to a controller ,which in turn shows the data to an HTML template.
So, If you navigate to another state or url and another controller loads , then the previous controller with all the data and the $watch will be unloaded, but new ones($watch) will load from the new loaded controller(if there are any).
$watch are never removed by itself, they have to be removed manually.
You should go through $watch lifecycle : $watch life cycle
No, the $watch list is updated as per the html which is being rendered by the browser.If you change template inside the page, the browser will have to render the new expression.
I think this youtube video would help you in getting
I have a login page, which is just a simple form in the center of the page with no header, footer or sidebar. My regular pages will have a sidebar, header and footer (these 3 are directives). I call all my templates in ng-view, depending on the routes.
I want to place my directives outside ng-view since they'll be common across all the pages except login and I don't want them to be fetched on every URL change.
How do I have a login page without the 3 directives?
I created a small plunk to offer you a solution to your issue.
this is the base of the solution:
<ng-include src="appVm.templatetoShow">
</ng-include>
in the Appcontroller :
function AppController() {
this.templatetoShow = 'login.html';
}
I included a couple of templates that gets loaded when needed.
After some rereading, I made a new plunk to show you how this can be done.
The hiding part is simple, just add some CSS into the mix, and you won't see
anything from your main page.
Added some cloaking to prevent FOUC, and wrote a couple of lines to show
an authentication system.
I introduced an User service that you can inject wherever you need the users
data.
Is this more in what you wanted?
I dont know if I get what You really want to do, but i would suggest to use ng-if
such ng-if may look look like this:
<div ng-if="notLogin"> here is Your navbar contents. Directies, anything You need </div>
and then in controller -
$scope.notLogin = $location.path() !== "/login"
If You have directives for footers, navbars etc, i think You can do that in directive controller and hide all content of directive there, so directive will be empty.
You may also use global controller to do that job and wrap those directives in divs like in my example. Doing it in directives looks cleaner though.
Hope its what You need.
you can use ng-if to conditionally display/hide them on UI. Please note that ng-if is different than ng-switch. The ngIf directive removes or recreates a portion of the DOM tree based on an {expression}. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM.
More details - https://docs.angularjs.org/api/ng/directive/ngIf
Qucik Steps -
create a shell page and set the header, footer, sidebar and a view
use ng-if={{User.isLoggedin}} for header, footer, sidebar and login
set User.isLoggedin to false when user is not logged in
Set it to true once user loged in
Directives are shared across all views if you use the same controller however using different controllers is not adviced either. what makes you uncomfortable with that ?
have a look at this post:
https://stackoverflow.com/a/16213055/1218551
best wishes:)
I'm fairly new to angular, after using a video tutorial and reading some documentation, I decided to rebuild an old app of mine as an example with angularjs.
So this app has a table showing some data. It has a form underneath which helps you modify the data from the list. You have a button on each line which allows you to edit the line, it then fill all the fields in the form and you can then save or cancel your changes.
I made a controller to handle the list, it works fine, it gets a json from http.
I used ng-click on my edit button to trigger a function in this controller, giving it the whole object it's supposed to edit.
I made a controller to handle the form in which the edit should take place and I don't really found a 'non-hacky' way to pass the data from the list controller to the form controller.
So, my question is : what is the best practice and/or the common way to get this data from my list controller to my form controler ?
It depends how you are using the form controller. If it's being used within a template using ng-controller attribute, then this controller has access to parent scope, so you can work with list controller's data. (although note some scope-inheritance quirks solved by "dot notation", explained nicely by egghead.io: https://egghead.io/lessons/angularjs-the-dot)
If you're launching your edit form in a another url (e.g. /items/2/edit) and handle it in a routing configuration, then you can use resolve property to pass any data to the controller: $routeProvider docs.
You can pass the entire object as parameter
<row ng-repeat="theModelInRow in modelList" ng-click="edit(theModelInRow)">
if form controller isn't a nested controller of list controller on view, then you can use rootScope.
[And a second question (see below) - rootScope variable set in one controller not visible in a second, sibling controller?]
Possible Duplicate: angularjs $location.path only updates URL on second click - the cause of the problem and the answer does not seem relevant in my, more basic, situation
As per the angularjs docs (https://docs.angularjs.org/guide/$location):
[The $location service]
Maintains synchronization between itself and the browser's URL when the user
...
Clicks on a link in the page.
I understood that $location.path() reflects the current url in the browser, but when I click a link to change the view, exhibits strange behaviour: $location.path() does not 'change' the first time one clicks on a link, and every time thereafter it will change to the link that was clicked the previous time
To see this go here: http://jsfiddle.net/7Ah2W/
I attempted a workaround whereby I must manually set $location.path() using the setter overload.
In doing so, I found another flaw in my understanding of angularjs. I tried setting a variable in the rootScope to reflect the 'current path.' The idea is that views would automatically detect the change in the variable and update. Does not every scope inherit from rootScope?
Here is a jsfiddle
Why is my expectation that $rootScope.currentPath, being changed in 'NavCtrl' and updated in 'CtrlTwo' not being met?
My end goal is to have my navigation bar automatically change when a link in the view is clicked. Similar to https://console.developers.google.com where if you click your project, the navigation to the left changes to API&Auth, settings, etc.
The reason it seems to always be "one behind" is that you're accessing the $location.path() before the actual angular page process can run. Strangely enough if you just add a $timeout with even 0ms delay, it'll work as intended.
$timeout(function () {
$scope.currentPath = $location.path();
}, 0);
jsFiddle example
$rootScope is the global scope, as opposed to the regular $scope which is basically the glue between the controller & view.
For example I set $rootScope.test = 123; in your first controller, and in the second controller I alert that variable, and get the result. jsFiddle $rootScope example. Be careful with $rootScope, it creates globally scoped variables
I am implementing the Angular ui bootstrap modal from
angular-ui-modal
The basic design exemplified by them is on the plunker next to it.
However my application requires it(the modal) to be implemented multiple times in the same single page web application (for saving loading etc).
In this plunker have modified their basic plunker [link : see my plunker here]
In the above plunker I am trying to apply dynamic binding between two controllers.
as in :
I want the value of "checkBind" from the inner controller modal template to be reflected in outer controller.
I know this is not possible like i am trying to do it because the "scopes are different".
Now i am not so convinced for using watches / broadcast /services for this
"petty modal thing".
I have few questions :
Do I have to create a separate controller for using the angular ui modal.
How can i use the "OuterCtrl"(in my plunker) to somehow write all the modal invoking and handler methods(like $scope.open.... $scope.ok .... $scope.cancel etc).
how can I directly bind the value of checkBind from the modal to the outerController in the least code possible(i mean by ignoring the watches services etc)
If "3" is possible then I can really ignore 1 and 2 (but i would still want to know the answer)
I know I am missing something here. Please tell me what is that.
Thanks in advance
I am new to angular and your english is a bit difficult to follow, but can't you instead set it to modal.checkBind and then put that property in a higher scope?