I use a same controller twice on my page, with same data, but i display it not in the same way (not same parts of the array).
I can see with ng-inspector that the scope is correctly updated when i perform some change, and it's duplicate. But in the view, it's doesn't change ! A simple param to false by default and passed at true with a simple timeout, in the view, it's always to false.
If i display only one time the ng-controller, the view it's updated.
How to correct that ?
Ok, so you didn't actually give much in the way of code, but this sounds like you're falling victim to one of the classic scope blunders. The first thing to try is to use properties of objects, not primitives on the scope.
This means instead of using this code ---
$scope.myBool = false;
{{myBool}}
use this code ---
$scope.myBool = { value: false };
{{myBool.value}}
The reason being is that Angular likes to do funny stuff like use prototype for new scopes. This means you'll get the prototype of the parent scope, and then when you instantiate your scope, you can override the parents prototype with your new value, without changing the parents value. You get past this by using an object on the scope instead.
The second option that might be occurring is you're doing something that isn't causing an angular digest cycle to happen. You might need to manually kick one off.
Without seeing any code, there's no telling, though.
Related
I am learning angular js and have now a question where I couldn't find the right answer yet.
in the template HTML, you can use expressions to show the scope variables or call scope functions. But I see all the time different versions of it.
{{name}} shows the variable and binds it
{{::name}} the same thing but without binding
userdirective="{{::key}}" But what is the difference here?
ng-if="::field.sortable" With ng-if they are not using {{ but with there userdirective they do?
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}" And then there is the last one with just one {. Thats when you create an object.right?
Maybe someone can help me to understand all of it.
Thank you very much for your time. Pat
{{name}} as you say is two-way data-binding
{{::name}} one way databinding
userdirective="{{::key}}" is the interesting case. This statement uses one-way binding into the userdirective ... which means after the $digest it just says userdirective="someValue"
So the userdirective gets that value as a plain value. Now I would have to test it but in the scopepart of the directiive it should say # so it gets read as a string and not as a expression.
The last one is simply as any JSON you build
{ name: value?true:false }
setting value according to conditions that angular evaluates, with a bit of magic involved :D
hope that helps
{{ anything here}} - That is angular expression interpolation. Angular interpolation - here you can find more about that. Basically idea that it interpolate anything you will put inside those brackets. So if you will put expression with some calculations or just variables related to current scope it will convert all variables to their values and apply calculations.
For instance: {{scopevar1 + scopevar2}} in case this variables has some values, let it be 1 and 2, as result we will see 3.
:: - This mean one time binding. For instance {{::scopevar1}} it will be interpolated once and will not check for changes of scopevar1, always stay as first value. Even if scopevar1 will change every second, the value in template will be the same. Angular Expressions - here you can find some live examples and more information.
userdirective="{{::key}}" - This case is nothing more then assigning dynamic value to your directive. UserDirective expectes to get a simple value, but we have it inside our scope, so we need to say: Hey, angular please interpolate scope variable - key, but only once, so my directive will get value, and will not looking for updates of key. And angular does it with pleasure!
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}"
The last case is when your directive expects to get some kind of specific JSON. And we don't want to build it inside of controller. It is sometimes easier to do such things in the tempalte. So we put specific object with two properties: condition, mdColors. And saying that first property assigned to result of function, and second one is simple object {color:'primary'}.
That's it!
{{var}} is a two way binding expression and {{::var}} is a one-way binding expression. expression with :: will not change once set, it is a candidate for one-time binding.
go through : https://docs.angularjs.org/guide/expression for better examples on these
{{name}} is the regular case you will find. You basically print the variable name and update it once it changes.
{{::name}} is the same but your value will not receive updates once it stabilises.
So in the first case, your template updates once name is changed. In the latter, it isn't.
userdirective="{{::key}}" is a one-way one-time binding. Leave the :: out and your directive receives updates if key changes. However, if the directive changes key, it will not update the parent.
ng-if="::field.sortable" is a two-way binding. The changes go both ways. In this case, field.sortable is watched by the directive.
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}" is used when you want to build adhoc-objects. A popular case is ng-class as well. You may build this object in the controller as well as you should not put too much logic in your template.
In any case, it is advisable to read the excellent docs https://docs.angularjs.org/guide
I am having issues with something which might imply I am missing something conceptual. I am using a view with a controller which populates from a couple of different services(asynchronous). Everything works fine the FIRST time the view is navigated to. All the expected elements get populated in the controller and the dom is rendered perfectly. However, the SECOND time a user navigates to the same view, the DOM does not render all the elements. I have put breaks in the code and have confirmed that the data is populated by the service exactly as it was the first time.
I put a break on a click event so I could inspect the scope post rendering. As expected the first time it is rendered, everything is as expected. The second time, despite watching the scope variable get set, when I inspect the scope post rendering the variable is undefined!! I have looked to see the $id of the scope. I can see that the first time the $id of the scope is the same through the whole initialization and rendering. The second time the controller is initializing the same scope but when I inspect post rendering I can see that the scope has changed and is now different from the one used by the controller to initialize. I don't understand what created this second scope OR why the first scope was used to initialize the controller.
So my question(s) to the AngularJS folks are as follows:
1. Are there differences in how Angular behaves from the first and then subsequent route events to the same route. I have noticed that the pages render faster.
2. How do $digest/$apply come in to play? It won't let me call them because I get the inprog error.
3. How/approaches to debugging this? I really don't understand where to go with this. Its as if I have lost the two way bindings.
Thanks.
I'm trying to change an input box value referring to its model.
The input box is inside an ng-repeat, that gets its elements from a function and not from a variable.
Is there a way for the application to print the model full path/name so that I can refer to it from the controller? (Note that the models are working, since a division beneath it with ng-show responds properly to the input model being filled.)
In general, you shouldn't use a function inside an ngRepeat. With the way the digest cycle works, your function will end up getting called multiple times. That's not very efficient. Instead, you should run the function from your controller and assign it to a scope variable that you pass to ngRepeat.
As it turns out, this makes the solution to your problem quite easy. You could for example use each item's $index to reference it from the controller.
If you post a fiddle or plunker, I can update this answer with something more specific. But it's hard to say more without some code.
Here's a strange behavior I want you to help me to examine: http://jsfiddle.net/m3Z8r/2/
I'm curious about why Angular calls symbolsLength() function more times that I've expected:
From the first time it was called twice (was expected to be called only once)
When switching from template1 to template2 it fires again (but there's no obvious need)
If you set initial templateName to "template2", function symbolsLength() will not be called, which is fine.
Please, can someone explain me what's going on here?
P.S. I understand that there's no need in symbolsLength() function since we can just write {{ symbols.length }}, but let's pretend that this function does something very important, for example, contacting service.
1. From the first time it was called twice (was expected to be called only once)
I stepped through the code and saw that this is because each watch function that is created for any binding holds a last value property and in the first phase the last value is different than the expression value which sets the dirty flag to true thus triggering a new pass.
2. When switching from template1 to template2 it fires again (but there's no obvious need)
I doesn't matter that the scope value hasn't changed once a new template is included new watches are created so step 1. is repeated
First I create some backbone views:
(function() {
var SomeView = Backbone.View.extend({ ... });
// finally on ready
$(function() {
// init my view
var v = new SomeView({...});
});
})();
Now, as we can see, I am instantiating the view inside the jQuery ready function, and assigning the instance to a local variable, which will be lost once the function exits. But, I notice that my view just works perfectly -- i.e., even though I am losing the reference to the view, it just works.
I guess this is because there are many closures involved, and all the required variables are actually preserved inside those closures.
So, my question is: is this alright to instantiate the views like this. Is it OK to not save the reference to it.
If you never need a reference to the view again, this is totally fine. You can render the view after instantiating it (or even do it in its constructor) and it will insert the generated HTML in the DOM (depending on the options you have set on the view).
Of course if you need to call some view methods later from some code outside the view you will need to keep a reference to the view around somewhere.
Your understanding is correct, if you do not need to call this view from the outside, then of course you do not need to record this reference.
However, your example is too simple, the actual situation of general need to record this reference.
btw:There are a lot of backbone of best practice, and I hope useful for you: http://ricostacruz.com/backbone-patterns