I have been struggling a long way in a issue, wherein I need to update a parent obj from directive scope. I need to fetch some data using $http and fit this data against a property in original parent Obj.
However, after doing this, the view gets updated but somehow the model binded to these view become undefined. Since the view are updated with new data, somehow the models are becoming undefined after that.
Only now I came to know that, $http triggers a $digest, so I think that is the cause of my issue.
What can I do to avoid my models becoming undefined and the fetched values to remain intact in original object.
Just to make things clear, before I attach a wrking plnkr. here is what I mean:
I have a obj $scope.Obj. I have binded the input fields in directive template with this object using 2 way binding like
<input ng-model = Obj.something.something2[$index]/>
Now say I made a API call and update my something2 in $scope.Obj as:
$scope.Obj.something.something2 = APIResponse.something3
The values from new object something3 are visible on UI, but in backend after this
$scope.Obj.something.something2[$index]
becomes undefined.
Pls suggest possible reasons for this...
The other models are becoming undefined because you are replacing the object. Instead you should use angular.extend.
angular.extend($scope.Obj.something.something2, APIResponse.something3);
For more information see the AngularJS angular.extend API Reference.
Related
while building a very large scale angular application i came across a performance issue. all my components and views heavily depend on data bindings, there ng-repeats everywhere. so i decided to remove all the 2 way databindings by adding {{::scopevariableName}}, now since there is no 2 way data binding my question is will the view update if modal value is changed in the controller?
function myCtr(){
var that=this;
this.scopevariableName='hannad'
this.someFunction=function(){
someEvent(function(callbackData){
if(callbackData){
that.scopevariableName='new value for scope variable'
}
});
}
}
<p ng-bind="::$ctrl.somevariableName"></p>
from the docs: One-time expressions
will stop recalculating once they are stable, which happens after the
first digest if the expression result is a non-undefined value.
My understanding of one-time binding is after the first initialization of the scope variable if the object value changes the view will NOT change.
because the watchers are not in effect.
ex
$scope.myVar=null;
<p>{{::myVar}}</p>
if the there are any changes to $scope.myVar those will not effect in the view
because it will take only its first initialization value. thats null.
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.
In a controller, when I get a resource from a service
$scope.myVariable = MyObject.get($scope.id);
then myVariable is not defined as MyObject since it will be resolved later. Is there a way to inspect the variable in the controller (not in the service), for example for debugging or logging? Basically I am looking for something like
console.log("myVariable now has property "+ $scope.myVariable.myProperty);
From AngularJS Doc to $resource, you can read that:
It is important to realize that invoking a $resource object method
immediately returns an empty reference.
Once the data is returned from the server the existing reference is
populated with the actual data. This is a useful trick since usually
the resource is assigned to a model which is then rendered by the
view. Having an empty object results in no rendering, once the data
arrives from the server then the object is populated with the data and
the view automatically re-renders itself showing the new data. This
means that in most case one never has to write a callback function for
the action methods.
But, if you need to print the value of $scope.myVariable once it gets populated, you will have to define a callback function:
$scope.myVariable = MyObject.get($scope.id, function(myVar){
// From now, myVar == $scope.myVariable
console.log("myVariable now has property "+ myVar.myProperty);
});
i'm using angular js in my website and i'm getting a strange behavior when i update my model.
My model is an json complex object like this:
$scope.DataSource = {prop1:"", prop2:[{a:1, b:b2}, {a:3, b:4}], prop3:"value"}
use a controller to edit object an use custom directives to edit separatelly child objects like in prop2 ( in this case are tabs ).
My problem is that when i update $scope.DataSource the previous generated DOM elements are not removed or updated, i just get a duplicated UI for each object in Prop2.
is there any way to force angular to update or remove previous generated elements? preventing a duplicated tabs(in this case)?
Duplicated DOM elements are likely the result of duplicated data in the scope associated with the view. Without any code, it is not clear if the scope generating the view is tied to a controller or a directive. Try logging the scope that the view is generated from to the console.
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