Change placeholder of input from angularjs directive wake scope model 'undefined' - javascript

So I have some trouble with my angularjs application. I try to implement a specific directive that make allow to translate my app easily. It works well on my text fields, but it doesn't work on input field to change my placeholder.
To be clear, here you can see some code sample :
http://plnkr.co/edit/GUS2FYCxA6wAOtkoxG66
$scope.validform = function() {
console.log($scope.valuefield);
};
As you can see, when i click on the button, my input model "valuefield" is "undefined". Or i want to see the value of the input.
What seems really strange for me is that the directive change the placeholder, but do not touch at the model.
I think I have to be more specific on the scope definition of the directive, or to use some $watch function but I am not sure how.
Can anyone guide me on this?

Ok, so finally it was pretty easy.
I only had to change my directive parameter from
scope : true
to
scope : false
By doing this, my directive is using the exact same scope than the controller. So The scope controller is not change and steal working as it should be.

Related

Angular js : ng-model default value of input is not set in model

I am using ng-model to link input values with model.
If I set default value in input box it does not show in $scope, but If I change anything in this input I can see changes.
<input type='text' id="save_quote_email" name="save_quote_email" ng-model="AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress" value="praveend06#gmail.com" />
{{AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress}}
I can set this value in controller, then it will work, but such values will come in form when my html loaded.
First, you shouldn't use ng-init in this case.
From docs:
This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit, such as for aliasing special properties of ngRepeat, as seen in the demo below; and for injecting data via server side scripting. Besides these few cases, you should use controllers rather than ngInit to initialize values on a scope.
Then, simply do it in your controller:
AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress = "praveend06#gmail.com";
Add
ng-init="AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress='praveend06#gmail.com'"
ng-init="AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress='praveend06#gmail.com'"

What is the best way to handle events in AngularJS in this case?

I am absolutly new in AngularJS and I have the following doubt about how to handle event in Angular.
So I know if in a view I have something like this:
<input type="text" ng-model="handle" />
it means that exist a 2 way binding between this input element in the dom and an handle variable into the Angular $scope, for example:
$scope.handle = '';
So any change that happen into this input object implies a change of the handle property in the $scope and vice-versa.
So, into the Angular applcation, I can explicitly declare a whatcher
// I explicitly declare a whatcher on the handle property: when the value of this propertu change the function() is performed:
$scope.$watch('handle', function(newValue, oldValue) {
console.info('Changed!');
console.log('Old:' + oldValue);
console.log('New:' + newValue);
});
So it should have the same meaning of manually adding a classic vanilla JavaScript EventListener (by the addEventListener() on the object that I want to observe in a classic old vanilla JavaScript application (that don't use Angular).
When something change on the input value the function associated to the whatcher is performed.
Ok it is pretty clear for me.
Now I say that I can also do something like this.
Into the HTML code I can have something like:
<input type="button" value="Click Me" ng-click="alertClick()" />
And in the Angular controller I will have something like:
$scope.alertClick = function() {
alert("Clicked !!!");
}
So it seems like the ng-Click directive perform a function that is a $scope field when there is the click event on the button.
But can I do the same operation as done in the first example? Can I do it declaring a whatcher on the button if it is associated to a model object by the ng-model="handle" directive?
When is better use the first method and when is better the second method to handle events in AngularJS?
ngModel is used to bind an imput form the UI to your controller
ngClick is just a regular javascript expression that have access to your controller scope that will be executed at the click event.
Here you have to use ng-click.
With angular a good practice is to avoid using function like addEventListener() or Jquery other function...
Because AngularJS wrap all this functionality and will run digest loop or other voodoo magic if necessary.
Use the click event. $scope.$watch should be used watching when something changes instead of things that are better for event handlers.
The tow "methods" you pointed out are not the same thing. At all.
The first, $watch, is intended to listen to the $scope changes. You can specify which property of the scope you want to watch, and when a change occur it will call you callback function. For more details, see the Digest cycle documentation.
The second, ng-click attribute directive, listen to the DOM events and evaluate the expression you pass in when the event occur.
In your case, for the button, you have two options. You can use the ng-click attribute directive to trigger a function in your scope OR use the ng-submit attribute directive in the form html tag of your inputs. That way you can trigger the form validation with the button or when the Enter is pressed.
See the documentation for ngSubmit.
ngModel applies to specific elements such as input,select, and textarea. As the result, you cannot use ngModel on a button. That is why you use ngClick to get the click event.

AngularJS - Bind input to value with filter and update it

I have an input bound to an object property and with a filter applied to it.
<input value="{{object.field | filter}}">
The problem is that if I programmatically change object.field, the value displayed inside the input doesn't change, however in the DOM Inspector I see the correct (new) value. I verified to digest/apply the changes to the scope and the object.field variable does change correctly, the issue seems to be only in the input displayed value.
I cannot provide an example since there's too much code involved.
Does anyone know where I should look for errors??
No need to set value in that way. ng-model takes care of it.
Valid syntax is:
<input ng-model="object.field">
For filtering you can look at this answer:
Using angularjs filter in input element
I think you should use ng-model to bind your data into input box instead {{expression}}

angular ngClass evaluation

I've been learning AngularJs and have built a very basic Angular app. In one part of the app, I've used ngClass at a div element like
<div ng-class='{"some class": aFuncTruthyOrFalsy()}'>
<!-- aFuncTruthyOrFalsy() is defined in the controller for this view-->
Now, there's an input element in the view that is non-related to the above element and does not relate at all to any of the values checked in the function above.
I noticed that every whenever I type something in the input field (change event, keypressed event) it causes a re-evaluation of the ngClass. (I've put in a console log inside the aFuncTruthyOrFalsy function). I'm not able to determine which all events are bubbling to cause the reevaluation.
It seems to me that ngClass reevaluates at every single event in the page.
Can anyone please explain/elaborate this behavior?
Is it possible to cache the evaluated class at the initial load of the view?
What if there are multiple ngClass being used in the same view and each of the expression evaluation is delegated to some function that again does some multiple operation to come to get the evaluated expression?
Angular binding is using $watch to monitor changes in the function value. The digest cycle is calling your function to compare the result with last value.
This article is nice explaining this
http://tutorials.jenkov.com/angularjs/watch-digest-apply.html#watch
I suggest binding to scope variables instead of functions. i.e. have a variable in the scope that will store result of that function, and you update that whenever required.
after all you don't want to call methods from your view probably.Your current setup leaves the door open to make the whole MVC concept void,e.g. someone later add functionality inside that method that was supposed to be just a getter.
When something is changed in the scope AngularJS automatically triggers a $digest cycle by calling $digest(). When the $digest cycle starts, it fires each of the watchers.
Angular sets up a watcher on the scope model, which in turn updates the view whenever the model changes.
So when you change something in the scope, all the watchers are fired and the model is reevaluated.
Here is a good article on the topic: Link
You can do something like
<div ng-class="{'background1': color.back}">
<label> <span>{{emp.comp}}</span> </label>
</div>

Weird Angular ng-model issue

I have a weird question regarding my Angular app.
I wanted to get the input texts when user enter texts in the input box.
my html
<input type="text" class="form-control" ng-model="texts" ng-change="type()"/>
my js
$scope.type = function() {
console.log($scope.texts)
console.log($scope) //doesn't see texts property either
}
However, every time I type something, the first console log shows 'undefined'. It's like controller can't find the texts property. Can anyone help me this weird issue? Thanks a lot!
This can be accomplished by using angular's two-way data binding system:
Data-binding in Angular apps is the automatic synchronization of data
between the model and view components. The way that Angular implements
data-binding lets you treat the model as the single-source-of-truth in
your application. The view is a projection of the model at all times.
When the model changes, the view reflects the change, and vice versa.
This allows us to synchronize the properties of our controller's scope by binding to them in our html.
So, we might define our controller like this:
myApp.controller('SomeController', function ($scope) {
$scope.text = "";
});
Now, we can use this in our html like this:
<div ng-controller="SomeController">
<input type="text" class="form-control" ng-model="text" />
</div>
The important thing to notice here is the ng-model directive. Here we bind the text property we defined in our controller to the <input> field. Now, with two-way binding, if we type into the input field it will automatically update the text property. This way we can access the value of the input field within our controller without having to do any extra work.
Here is a plnkr with a working example: http://plnkr.co/edit/xEkoDbPxwrWgGfuEiS3a?p=preview
Hope this helps :-)
$scope has to be passed in to the controller. Check your controller arguments.

Categories