There are toggle two button (edit and submit), which button should work like toggle show/hide style on click
<button (click)="showEditBtn = false;" *ngIf="showEditBtn;"> Edit</button>
<button (click)="showEditBtn = true;" *ngIf="!showEditBtn;">Submit</button>
I need showEditBtn variable should be true in default without touching script file
Is it possible to assign a value to a variable in the template, like below example?
<div> {{ let showEditBtn = true }} </div>
stackblitz example
Figured out. It is a bit of a hack. But works perfectly
<div *ngIf="true; let showEditBtn">
<div> {{ showEditBtn }} </div>
<button (click)="showEditBtn = false" *ngIf="showEditBtn"> Edit</button>
<button (click)="showEditBtn = true" *ngIf="!showEditBtn">Submit</button>
</div>
You cannot create or set value in a variable inside interpolation {{ }}, interpolation is only used to print the output (value of variable).
Angular Interpolation is a way of data binding in Angular. And it will allow user to communicate between component and it's template (view).
String Interpolation is a one way data binding. In one-way data binding, the value of the Model is inserted into an HTML (DOM) element and there is no way to update the Model from the View.
Hope given link may help to understand well.
I highly recommend to not set or update variables in your template. All of your logic should be in the controller.
here is a simple example of how you can do it
app.component.ts:
public isEditMode: boolean;
public toggleEditMode(): void {
this.isEditMode = !this.isEditMode;
}
app.component.html
<button (click)="toggleEditMode()" *ngIf="isEditMode;"> Edit</button>
<button (click)="toggleEditMode()" *ngIf="!isEditMode;">Submit</button>
There is no way in Angular2+ to initialize the variable value in the template. You must look into the ngOnInit() function.
Related
<a #globalVar>
<input [(ngModel)] = "newTitle"
#newBlogTitle_l = "ngModel" >
<div *ngIf = 'newBlogTitle_l.value === "" ' >
globalVar.value = false
</div>
<button (click) = "onSave()" [disabled] = "globalVar" > Save </button>
If there is nothing in the input box, I expect the button to remain enabled.
What's the way to achieve that?
(This is just for learning purpose.)
It is not a good idea to modify values of variables in the template. It makes it hard to maintain in the long run. Variables modifications should be almost always done in the controller.
Besides, when there is a variable bound to [(ngModel)], you can use it directly to set the state of other elements. Try the following
Controller
export class AppComponent {
newTitle: string;
}
Template
<input [(ngModel)]="newTitle">
<button [disabled]="newTitle">Click me</button>
Working example: Stackblitz
I think you're going for an angular JS approach, where we can define global variables in HTML and set values. Why not just write the condition on the disabled attribute as shown below
<input [(ngModel)] = "newTitle"
#newBlogTitle_l = "ngModel" />
<div *ngIf = "newBlogTitle_l.value" >
test
</div>
<button (click) = "onSave()" [disabled] = "newBlogTitle_l.value" > Save </button>
https://stackblitz.com/edit/angular-vgxn4t?file=src/app/app.component.html
I'm new to Angular, just a question on the difference of Built-in Directives and property binding, below is some code I saw:
// ... just js expression, not relevant here
<div [ngClass]="'text-white' + ...">
Hello, World.
</div>
<div class="form-group m-2">
<label>Name:</label>
<input class="form-control" [value]=... />
</div>
so why we can't make ngClass a standard property binding just like [value] as:
<div [class]="'text-white' + ...">
why it has to be a directive?
Its possible to use [class] directly. It's even possible to combine with ngClass like in the following:
In app.component.ts
isActive = true;
componentClass = 'my-class';
In app.component.html
<div [class]="componentClass" [ngClass]="{ active: isActive }">hello</div>
If you inspect your html you will see this result:
<div _ngcontent-gej-c0="" class="my-class active">div</div>
But I wouldn't recommend it. When you will be constructing reusable components better let class attribute available for the end developer.
Literal values should be passed without brackets around the attribute.
ngclass="text-white"
If the value is variable you can pass it dynamically by wrapping the attribute in brackets:
Component.ts
myclass: string = 'text-white';
Component.html
[ngclass]="myclass"
You can also pass an object where each project is a CSS class name and the value true or false, true stating the class will be used false stating it will not.
[ngClass]="{'row': true, 'container': false}"
There is nothing stopping you building that dynamically too.
Component.ts
getClassses(): any {
return {'row': true, 'container': false}
}
Component.html
[ngClass]="getClasses()"
In my app, i am calculating total bill and displaying on my view. First time its work fine. But when I increment the $scope.bill_total it is not updating the view. But in console it is changing. I have tried $scope.$apply(). But it is throwing error.what are the reasons of view not get updating in general case Can anyone explain it?
HTML
<div id="total" class="col col-30 cart-item text-right text-black">
Bill Total<br/> ${{ bill_total }}
</div>
<button class="button button-small button-light" ng-click="increment()"> +</button>
JavaScript:
$scope.calculate = function () {
$scope.bill_total = parseFloat($scope.gross_bill) + parseFloat($scope.taxes) + parseFloat($scope.tips);
}
$scope.calculate();
$scope.increment = function () {
$scope.gross_bill++;
$scope.calculate();
console.log($scope.bill_total )
}
Need to see more of your code, but why are you updating gross_bill when you are expecting bill_total to change?
If you aren't using gross_bill in your template, it won't be watched and hence changing it's value won't redraw the view.
So, modify things that are bound in your template. If there's some reason I'm wrong and you need to do scope.apply, and maybe that's the case, try wrapping your code in a $timeout which will trigger a digest, is the 'recommended' solution preferred to calling apply directly.
notes on apply vs timeout
as we can only see part of your source code, it looks all good.
to test if everyting is in the same digest scope, you can manually do an async apply:
$scope.increment = function () {
setTimeout(function () {
$scope.gross_bill++;
$scope.calculate();
$scope.$apply();
console.log($scope.bill_total );
});
}
and pls also double check below points:
if bill_total is one-time binding {{ ::bill_total }}
if the directive scope is isolated with one-way binding bill_total
The problem is probably that $scope.bill_total is not an object and therefore cannot be watched. You need to change it to something like $scope.bill_total = {value: 3}. Then when you update the value it should be updated correctly in your view. There should be no reason to call $scope.apply since you are within a digest cycle already.
Make sure to change your html to :
<div id="total" class="col col-30 cart-item text-right text-black">
Bill Total<br/> ${{ bill_total.value }}
</div>
I've come a bit stuck in my angularjs project.
I run a for loop to query some nested JSON data and output it in 3 different variables inside an ng-repeat. So it makes up a title where i have the control over the elements that make up the title {{ number }} {{ shots }} {{ goals }}.
However, my knowledge of angularjs is stretched here because when I click on one of the events (from the ng-repeat list) it gives me a new tab, but I want to bring the title of that event to the new tab.
I can't call it as a scope variable as the last variable is still being held in there. I thought about assigning it as a new variable.. but was unsure how to actually do that in angularjs.
Here is the code i'm working with:
<li ng-repeat="event in events.events">
<div ng-if="actionType(event)" >
{{number}}
{{shots}}
{{goals}}
</div>
<a class="showPlayer" ng-click="showPlayer(event)">
View more stats
</a>
</li>
my angularjs is just a standard for loop which looks for values inside the js and assigns them as variables.
Any advice is very much appreciated.
EDIT: 24 hours later and I still can't crack this (very frustrating).
I'm not sure if there is a way to grab the string from the ng-click and clone that?
I don't want to have to run another check for the title when I already have the information, surely there is an 'angular' way to do this??
Please try this I am not sure but it might help you
<li ng-repeat="event in events.events">
<div ng-if="actionType(event)" >
{{event.number}}
{{event.shots}}
{{event.goals}}
</div>
<a class="showPlayer" ng-click="showPlayer(event.number,event.shots,event.goals)">
View more stats
</a>
</li>
Try using $rootScope.
Define a rootscope variable where event is handled and write your title in html like you did. {{title}}
$rootScope.title = "example";
I'm building an interface with a lot of toggles to control what data is being filtered in a different part of an App's search results. Here is a codepen of it: Here
Coming from a jQuery/Backbone background, what is the most Angular way of toggling the 'active' state of any/all of the filter items? Essentially, almost any <li> tag presented here is a toggle-able feature.
In jQuery, I would put a listener on the view and wait for any click events to bubble up and toggle an 'active' class on the event.target. I want to do it the best way with Angular.
(Also, this is my first Angular project.. I am probably doing all sorts of things the wrong way. Apologies in advance.)
Edit: To clarify the question, I have an App Interface with 20+ possible filter attributes to control a separate module on the page. Every time someone toggles one of these filter attributes, I want to add/remove an 'active' class. Do I put an 'ng-click="function(...)"' in the ng-repeat for each controller? Or is there an easier way to manage this module-wide behavior (a la event bubbling, like in Backbone/jQuery) ?
Thanks!
You can do something like this:
<section ng-init="active = 'areaFoo'">
<div ng-class="{active:active == 'areaFoo'}" ng-click="active = 'areaFoo'"></div>
<div ng-class="{active:active == 'areaBar'}" ng-click="active = 'areaBar'"></div>
</section>
It will populate $scope.active for you, and is very angular as it leverages existing directives, manages the state on scope, and does not leverage dom api's or events outside of directives. There is really no need to involve the controller here, as its display logic.
Learn more about ng-class here.
Multiple active elements
<section>
<div ng-class="{active:areaFoo}" ng-init="areaFoo = true">
<button ng-click="areaFoo = true">activate</button>
<button ng-click="areaFoo = false">de activate</button>
</div>
<div ng-class="{active:areaBar}" ng-init="areaBar = false">
<button ng-click="areaBar = true">activate</button>
<button ng-click="areaBar = false">de activate</button>
</div>
<div ng-class="{active:areaBar}" ng-init="areaBaz = false">
<button ng-click="areaBaz = true">activate</button>
<button ng-click="areaBaz = false">de activate</button>
</div>
</section>
you could also toggle with something like this ng-click="areaFoo = !areaFoo"
I was able to come up with a solution I'm ok with, for anyone curious you can see a demo Here.
Here are the relevant code snippets:
<li ng-repeat='category in data' ng-class='{active: category.isActive}' ng-click='toggleActive(category)' >
<span class='solr-facets-filter-title'>{{category.catTitle}}</span>
<span class='solr-facets-filter-count'>{{category.catResults}}</span>
</li>
An ng-click calls a method on the Controller, toggleActive(category). The current data model gets sent to the method. In the JS:
$scope.toggleActive = function(category){
category.isActive = !category.isActive;
}
The function returns the opposite of the isActive attribute back to the li in question: an ng-class adds the active class for a truthy state of isActive.
I'm not a huge fan of how I have to adjust the data model with flags for active/inactive states like this, but it ends up working out for the best in this case. I can push those isActive states back to the $scope so that other parts of the App can run queries based on that information.