Angular template variable reference - javascript

Here is a weird problem in Angular:
<input #pin1 type="password">
<p>You entered: {{pin1.value}}</p>
If you type something in <input>, the <p>'s content will not change which means pin1.value does not have value, does it mean the variable reference #pin1 does not work?
On the other hand, if we add a function to pass the reference, it will work.
<input #pin2 type="password" (input)="test(pin2)">
<p>You entered: {{pin2.value}}</p>
where test=function(x){console.log(x);}
For this <input>, if we type something, the the <p>'s content will change to corresponding text which implies #pin2 works.
So, the question is, in Angular, why we must use function to pass variable reference firstly then we can use it, why we cannot directly use variable reference.

Firstly, that is not how binding works.
What you did is creating a reference to input Dom object. At the time of the creation, the value of that Dom element (input) was empty. hence no value showing in your <p> tag.
if you want to see the value as you type then you are looking for a 2 way binding like so
<input [(ngModel)]="pin" type="password">
<p>You entered: {{pin}}</p>
Assuming that pin is declared in your ts file.
As to why the value was updating when you introduces a function, the answer is because Angular will be calling that function test(pin2) whenever you type something into that input which results in running a detect change on the model.
Long story short, Angular is a Model driven framework, if you need a value, you shouldn't need to get the DOM element to get the value from there.

I may get an ambiguous answer, it may be related to event binding, which means "view-to-source", if we didn't bind any event, the view (user interaction) cannot pass data to source (the component class), so variable reference may not work, but there are still some question like the template references should not be related to source side, since such variables aren't member/properties of component class.

it is so werired behaviour in angular
this code not working
<input #inputval type="text" />
<app-newcomp [testValue]="inputva.value"></app-newcomp>
but if you add "input" event to the input element then it will work
<input #inputval type="text" (input)="someFunctionInTs($event)" />
<app-newcomp [testValue]="inputva.value"></app-newcomp>

Related

Where does Blazor store form data?

Interestingly, some input elements of Blazor Forms don't have the data stored in HTML as value (attribute) of the input-field. The fields doesn't even have a value attribute!
When I inspect and use 'Store as global object' functionality in chrome and check the value of the element in console (temp1.value), I can see the value.
I'm wondering where this value is being stored in the browser.
The value attribute is not set by changing the DOM's .value property.
Consider the following minimal example:
<input id=time>
<script>setInterval("time.value = new Date()", 1000);</script>
<input type=button onclick=alert(time.value) value=read>
You can inspect the clock and see that there's never a value attribute, yet the input's value property can be both setted and getted by script.
Thus, the value of the form input in your question can come from almost anywhere. It's likely embedded deep inside the other library support code that makes it easy to shuttle data back and forth, but that's speculation on my part. It's a JS variable of some sort, that much we know. The main thing is that attributes are not needed when making heavy use of JS.

quirks of input element in React

I'm new to React, sorry if my questions are trivial.
In React, if I write:
<input value="" />
then it will be an read-only field, and React forces me to add an onChange handler as:
<input value={this.state.greeting} onChange={this.handleChange} />
where handleChange() update component's state.greeting, therefore value gets updated too
Below are my questions:
Q1-why <input value="" /> is not read-only in plain html but read-only in React? How does React make it read-only
Q2-I found that if I write the code as below it also works, the input is not read-only
<input onChange={this.handleChange} />
and isn't that this approach better and more concise? because the internal value will get updated automatically in the browser, therefore we don't need to include an value attribute to read the data back from the state, which is unnecessary in most of times, so why I always see code like:
<input value={this.state.greeting} onChange={this.handleChange} />
Additional info:
some says it is controlled form elements that needs to have value attribute, but why we need to have a value attribute to read from the state? and when we type sth into the input, the onChange handler already updates the state, so it is still controlled.
To know how React makes your tags readonly, you will need to study the source-code that runs at your end and/or view the generated HTML. If still unsure about it, then you might want to send your first question to the authors of the tool.
The state is not on the server, unless you are polling or doing something of the like. It's in your browser as well. The value property specifies the initial value of your HTML element, that is, before you do anything your tag will have a value. In your case, your tag is controlled by React, but you need to initialize it. Benefits:
you will have the initial value
you will have a more readable code
your code will be written in the React-way, so you will not need to worry of unpleasant surprises

VueJS - How to apply directives to all matching tags?

I'd like to apply a directive to all input tags programmatically. Two reasons for this are:
I don't want to have to go through all inputs in my app to add the directive
If I want to change the directive against all inputs at a later date, it's in one place.
Is this possible? I've reviewed the docs but they don't seem to mention applying it in any other way than applying the tag directly to the element.
My current code is like so:
<input type="text" class="form-control input-sm" id="price" v-model="model.doc.price" v-floating-label>
I was having a brain dead moment it seems. I just need an input component. I can then change what I need on there and it will update everywhere the input component has been used and instead of using the standard html input tag, I'll use my component.
Long day ...
I've answered this question myself instead of deleting it in case anybody else has the same brain dead moment in the future ;)
As per Evan You:
Vue.js compilation happens when you instantiate/mount the root instance.
See https://github.com/vuejs/Discussion/issues/77#issuecomment-60339440
I don't think what your are trying to do is sane: search and replace, coming out of the box in many text editors or IDE, will be really helpful for your two explained reasons.
You can bind that directive to a condition like so
<input type="text"
class="form-control input-sm"
id="price"
v-model="model.doc.price"
:v-floating-label=(condition)>
If condition == true , v-model-float directive will be applied to your input.
Update 1: From the comments, the implementation will still be the same, except you control the condition from one place. That way, you can remove the directive at a later date by simply setting that condition to false.

Angular 2 form elements' attributes - correct syntax?

I was reading this artcle and in the article I see:
<input type="search" [formControl]="seachControl">
and
<input type="text" formControlName="street">
I am wondering what the correct syntax is for stating formControl and formGroup. Can I do something like
<input type="text" [formControlName]="street">
or
<input type="text" [attr.formControlName]="street">
or
<input type="text" [formControl]="street">? And more specifically how do the three instances differ?
[formControl]="seachControl" is what we call model binding, it's binding to the main form element i.e. search.
When you have a single form Element, i.e. search you're just simply model binding it to whatever variable you created inside your class and do keep in mind the type of the variable you bind to.
and as for the
<input type="text" formControlName="street">
since street here was created inside the main formControl element you don't have direct access to street variable. so what this directive is doing is telling that the main/parent element that this tag is should bind to the street you created inside the main formControl.
As for
<input type="text" [formControlName]="street">
I don't know but I think the formControlName doesn't actually do the binding it is sort of telling what this tag needs to bind to. And the syntax suggests that it will try to look for street variable inside your class bind it.
as you can see he says.
This is where the formControlName directive comes into play. It’s pretty much the equivalent of an ngModel and name attribute combination in template-driven forms. Each form control gets a formControlName directive applied so we can register the controls on the outer form
So you only need to bind the outer model since that exists/instantiated in your class and formControlName and formGroupName will take care of the inner elements.

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}}

Categories