In the documentation for angular.extend (https://docs.angularjs.org/api/ng/function/angular.extend), what is meant by "If you want to preserve original objects, you can do so by passing an empty object as the target"?
Related
I just learned about $scope.watch here https://stackoverflow.com/a/15113029/2241256.
It says that everything that is used in the view is monitored by angular. So I am wondering what happens when I am using an array containing big objects in a ng-repeat?
Say each object has an attribute: 'name', which is the only thing I use in the list. Will angular still look for changes in the whole object or just look at the 'name' attribute of each object?
AngularJS watches just that name property of objects because of showing on view. By the way, if those values which is name property don't need to be directly updated, you can use one-way data binding by adding :: before of variables. Like; ng-bind="::object.name". If you do this, AngularJS doesn't watch that variable of your object. Don't worry. If you update your array which contains all of this objects, AngularJS will update those name attributes because of updating array.
You can read this page of docs for one-way data binding.
Just the 'name' attribute.
Only what's used inside of a template (between {{ and }}), or registered manually ($scope.watch('myVar', function () { ... })) is watched for changes
Trying to have 2 way binding on an AngularJS directive while using primitive objects is not working, for example:
<custom-directive ng-model="variable"></custom-directive>
how can this be achieved?
In order to have 2 way binding in javascript (not just angularjs), we have to pass an object (this is caused by javascript's evaluation strategy - can read more about it here https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing). basically what is happening is that when we pass a primitive variable, its been passed by value and re-created, instead of been passed by reference. only objects are passed by reference.
So this issue can be solved by passing the variable's parent object, for example:
<custom-directive ng-model-name="variable" ng-model-parent="parentObj"></custom-directive>
and then, modifying in object in the directive as following:
parentObj[variable] = "whatever";
this way, we will keep the connection between the variable to the parentObj.
another option would be passing the model with the parent obj, for example:
<custom-directive ng-model="parentObj.variable"></custom-directive>
the dot is an important part of this example. its actually a best practice by angular to always pass variables with the parentObj-dot-property.
for additional information, angularjs actually has a documentation about it https://github.com/angular/angular.js/wiki/Understanding-Scopes
I just realized that if your directive isn't inside an ng-if it will work with primitive bindings. Maybe the problem is that your bind is inside an ng-if. Try to use ng-show instead. Maybe it will work.
Passing the primitive this way:
<custom-directive ng-model="parentObj.variable"></custom-directive>
Angular offers great possibilities for reading the status of an input field, like $dirty, $touched and so on. However, as far as I found out, that works only when accessing an input element by its name, like $scope.formName.inputFieldName.
But I need to access an input element defined in a directive template inside the directive's controller by the element's ID (and without the form name). Whatever I try, I don't get the special input form handles.
Something like
var myElement = $document[0].getElementById('my_id');
console.log(angular.element(myElement));
doesn't work. I get the DOM element itself, wrapped inside generic object context, but not the input handles Angular offers.
Use angular.element(myElement).controller("ngModel") to access the model controller of an input element.
For more information, see AngularJS element function API Reference -- jqLite Extras
In AngularJS is $scope actually the parent object's body? If so, does this mean that the controller in the image below (called "MainCtrl") is essentially setting two variables within the MODULE and that "categories" and "bookmarks" would now be available within the module called "Eggly?"
OR...
Is the function, passed in as the 2nd argument of the controller function actually NEWING UP a new empty object and passing that new object in as the $scope? That would indicate that the two variables are being set on the new object and the new object, with the new variables, would be set as the controller.
From a C# perspective
In C# it is common to pass in "this" when creating an instance of an object within an object IF the child needs to access the parent. The child would receive this and have access to any PUBLIC properties or methods. It appears that passing in $scope does something similar except that EVERYTHING in the parent is available from the child (probably a function).
Setting a property on $scope exposes the property to whoever sees this scope, typically child directives and controllers.
It doesn't set it "on the module" - whatever that means.
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);
});