This is regarding https://docs.angularjs.org/guide/interpolation#known-issues
The documentation says that "Your changes are likely to be overwritten, when the original string gets evaluated."
With the example:
style="color: {{ 'orange' }}; font-weight: {{ 'bold' }};")
Can someone please explain what documents is trying to highlight?
Related
I just started using Hugo with the Kiss template, but I cant seem to get variables to work.
In my page, I defined the variable imgPad here:
---
title: "Hugo Blog on Azure"
date: 2018-12-09T15:51:09-05:00
draft: false
imgPad: 14
---
Below, I try to use it like this:
<img alt="Deploy to Static Website" src="img/hugo-blog-on-azure/azure_storage_deploy.png" style="width: 500px; display:block; padding: {{ .imgPad }}"/>
In the browser the {{ .imgPad }} does not get replaced with anything. What could be the problem?
Thanks.
Look at Page Level Params
It needs to be accessed as
{{ .Params.imgpad }}
Note the lower case.
Didn't work for me, I get this as a result in the browser:
<img alt="Successful deployment" src="img/hugo-blog-on-azure/azure_storage_deploy2.png" style="width: 500px; display:block;
padding: {{ .Params.imgPad }}">
^^^^^^
There still is an uppercase letter.
As described in this thread, use in your fragment template, and in your front-page only lowercase variables.
Example:
ingredients:
- ingredient: Club Soda
amount: 4oz
- ingredient: Gin
amount: 2oz
- ingredient: Lemon Juice
amount: 1oz
- ingredient: Simple Syrup
amount: 1tsp
and
{{ range .Params.ingredients }}
{{ .ingredient }} {{ .amount }}
{{ end }}
Every variable is in lowercase here.
My question is in regard of best practice / preferred readability in Angular 1.X with ng-show and ng-hide.
When using ng-hide and ng-show, is it advised to stick to one and to alternate the value I am evaluating or should i alternate between the two in order to keep the value in the expression the same?
See the following examples. Is one preferred over the other and if so why?
Assume that there are only two states, sportSelected can be Hockey or Football that is it, so there are two states.
Using only ng-show and switching the value
<div class="col-xs-4" ng-show="vm.sportSelected=='hockey'">
NJ Devils
</div>
<div class="col-xs-4" ng-show="vm.sportSelected=='football'">
NY Jets
</div>
<div class="col-xs-4" ng-show="vm.sportSelected=='football'">
NY Giants
</div>
Alternating between ng-show and ng-hide to keep the value the same
<div class="col-xs-4" ng-show="vm.isHockeySelected">
NJ Devils
</div>
<div class="col-xs-4" ng-hide="vm.isHockeySelected">
NY Jets
</div>
<div class="col-xs-4" ng-hide="vm.isHockeySelected">
NY Giants
</div>
The top seems more clear to me but it could just be due to poor method and variable names. I am looking through the angular documentation and I cant seem to arrive at what the preferred result is. Is one preferred over the other?
Edit: Flagged this to be closed, I realized this is pretty opinion based like tabs vs spaces even though I think one solution has benefits over the other
ng-hide and ng-show both work in different ways. They are essentially CSS classes which either hide or show the specified div, depending on how the value evaluates.
<!-- when $scope.myValue is truthy (element is visible) -->
<div ng-show="myValue"></div>
if myValue evaluates to true then the div would be visible
<!-- when $scope.myValue is falsy (element is hidden) -->
<div ng-show="myValue" class="ng-hide"></div>
however, in the second example, the div would be hidden as the class is set to that of ng-hide.
also you can run ng-show or ng-hide to check if the value evaluates to false, like so: <div ng-show="!myValue"></div>
Due to the nature of the digest cycle in Angular, these checks will be ran on page load. If you do not want the div to be shown on the page, it can be recommendable to use ng-if, rather than ng-show or ng-hide, as it will not load on the page, as opposed to simply hiding it.
In the snippet below you will see an example working for both ng-hide and ng-show, using the value of the ng-model value response of the input checkbox 'checked'. Which gives a boolean response.
When it is clicked on, the value for 'checked' evaluates to true. When it is unclicked, the value evaluates to false. When the ng-model evaluates to false, it shows the ng-hide div, when the ng-model evalutes to true, it shows the ng-show div.
Further reading here: Angular ng-show documentation
#import url(../../components/bootstrap-3.1.1/css/bootstrap.css);
.animate-show {
line-height: 20px;
opacity: 1;
padding: 10px;
border: 1px solid black;
background: white;
}
.animate-show.ng-hide-add, .animate-show.ng-hide-remove {
transition: all linear 0.5s;
}
.animate-show.ng-hide {
line-height: 0;
opacity: 0;
padding: 0 10px;
}
.check-element {
padding: 10px;
border: 1px solid black;
background: white;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-ng-show-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
</head>
<body ng-app="ngAnimate">
Click me: <input type="checkbox" ng-model="checked" aria-label="Toggle ngHide"><br/>
<div>
Show:
<div class="check-element animate-show" ng-show="checked">
<span class="glyphicon glyphicon-thumbs-up"></span> I show up when your checkbox is checked.
</div>
</div>
<div>
Hide:
<div class="check-element animate-show" ng-hide="checked">
<span class="glyphicon glyphicon-thumbs-down"></span> I hide when your checkbox is checked.
</div>
</div>
</body>
</html>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->
Whether or not you use ng-hide or ng-show should be based on how you want the page to appear by default. If you are controlling the visibility of an element that will be hidden by default and only shown after the user completes some action (like selecting a sport), then you want to use ng-show. If the element is to be shown by default and only hidden after some user action (maybe a div that says 'select a sport' that disappears once a sport is selected), then you want to use ng-hide.
Using the directives this way will contribute more toward readability than worrying about how the boolean condition itself is specified. It also has an important practical benefit. If you use ng-hide for something that is supposed to be hidden by default, you might see the element flicker each time you load the page, because in early $digest cycles before your scope can be fully evaluated, the result of that condition will be falsy, which will cause the element to appear briefly before it disappears.
You've got the right idea in the top example (looks like you have a syntax issue with the quotes though).
How can I sucessfully do this?
ng-class="{'a':x, 'b':::y}"
Notice how I'm trying to bind only once with "y" but not with "x"
I also tried using multiple ng-class directives, like this:
<div ng-class="{'a':x}" ng-class="::{'b':y}"></div>
but doesn't work either.
The problem is that you can only specify one-time binding syntax :: at the beginning of the expression. Here your expression is an object literal and using :: before the second key value results in an invalid syntax. You would have to split them up and probably place one section in the class expression (There is no point using 2 ng-class directives).
Example:
ng-class="{'a':x}" class="someclass {{::{true:'b'}[y]}}"
Documentation
An expression that starts with :: is considered a one-time expression. ....
.a {
color: green;
}
.b {
color: blue;
}
.a.b {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<div ng-app>
<div ng-class="{'a':x}" class="{{::{true:'b'}[y]}}">Test</div>
X->
<input type="checkbox" ng-model="x">Y->
<input type="checkbox" ng-model="y">
</div>
Note: One time binding will keep the watch until it gets an non undefined value for the bound property. If the property value is available at the time view renders (i.e not asyncronous) you could just do
<div ng-class="{'a':x}" class="{{::y ? 'b': ''}}">Test</div>
as well.
I have a html page with this code
<p id="roonnameDiv" >{{chatRoom}}</p>
and an app.js with the following code . It reflects the value corrrectly but if I try to style it with color at runtime it doesnt not reflect on the html page
$scope.$parent.chatRoom = $stateParams.roomId;
$scope.$parent.chatRoom.style = {"color":"green"};
I even tried using ng-color but in vain . Have head using html-unsafe tags t add html5 code to angular variables at runtime , perhaps I could use that to provide style of element but could not find any examples .
Essentially the requirement is of having various styled ( color ,size and fonts ) in roonnameDiv using angular framework
..................Edit .............................
I used the ngstyle as suggested by answers below
$scope.$parent.chatRoom = $stateParams.roomId;
$scope.myStyle = {color: "green"};
however the output text was just plain grey . On exploring it thorugh chorome inspector , I found it is inheriting some styles through body.
Switching off the body color tag just turns the text black instead of green .
Following is the body
<body ng-app="xyz" ng-controller="AppController" class="ng-scope">
This is the body style
body {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 1.42857143;
color: #333;
background-color: #fff;
}
I want specific style class to apply for different text components without affetcting the overall body style . Could you suggest how to do so ?
You can use ng-style directive.
In Markup
<p id="roonnameDiv" ng-style="myStyle">{{chatRoom}}</p>
In controller
$scope.myStyle = {color: "green", background: "blue"} // Write all the required styles here.
More on ng-style directive at: https://docs.angularjs.org/api/ng/directive/ngStyle
try this
<p id="roonnameDiv" ng-style="chatRoom.style" >{{chatRoom}}</p>
<p ng-repeat="row in matrix">
<span ng-repeat="column in row">
<input type="text" style="width: 20px; text-align: center;" ng-model="column" ng-change="{{column = }}">
</span>
</p>
And on my controller:
$scope.matrix = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
I have little piece of code and I want that little text input box to be associated with matrix[i][u]. I know I can use ng-model= to make the text box be associated with a certain variable.
However, I want it to go both ways - changing the variable will change the text box value and changing the text box value will change the variable. However, when I have ng-model on an input text box I can't seem to edit its value, as it'll always "reset" to its default.
I know I can use ng-change but I made the middle line this:
<input type="text" style="width: 20px; text-align: center;" ng-model="column" ng-change="update">
And it didn't work to call the $scope.update() function. I also still can't edit the text box value.
tl;dr: How can I have a text box with an ng-model and allow editing it to edit both the text box value and the variable on ng-model.
Use it this way:
<input type="text" ng-model="matrix[$index][$parent.$index]" style="width: 20px; text-align: center;" />
Example: http://jsfiddle.net/cherniv/hcLVE/
It is not very elegant , but it is working..
Here's a directive approach which is a little more fun:
app.directive("matrix", function($compile){
return{
scope:{
ngModel:'='
},
restrict:"E",
link:function(scope, element, attributes){
var render = function(){
var template="";
scope.ngModel.forEach(function(row, r){
template+="<p>";
console.log(scope.ngModel[r]);
row.forEach(function(column, c){
template+='<span><input style="width: 20px; text-align: center;" ng-model="ngModel['+r+']['+c+']"></span>';
});
template+="</p>";
});
element.html(template);
$compile(element.contents())(scope);
}
render();
scope.$watch('ngModel', render, true);
}
}
});
which can be used <matrix ng-model="matrix"></matrix>
Just because I love directives. Running here: http://plnkr.co/edit/jI7Hi9LKXnDFBd0gXtNZ?p=preview
Use
row[$index]
as the ng:model in the input tag:
<input type="text" ng-model="row[$index]" style="width: 20px; text-align: center;" />
The reason why this works and using column does not work is this: The <input> tag will create a child scope by copying the parent scope. But column is a simple/scalar variable. Such a variable will really just be copied. Therefore you end up with a copy in ng:model which is not connected to the real variable in your matrix. This is the reason why the AngularJS people stress that you should always have something with a dot inside referenced by ng-model.
On the other hand, row is still a complex variable (Array) and not a scalar. Such a variable is "copied" by JavaScript not by creating a real copy but by just copying the reference to the data. So you end up with a second reference to the same data. And therefore row in the child-scope created by the <input> tag is still connected to the original row data in the matrix and two-way data-binding will work.
To stress this again: Never use something without a dot as ng:model. AngularJS used to have bad examples doing this on their webpage but it appears that they have mostly/all been changed. But as you can see in this example something foo[5] is also ok, because it still references a complex variable. foo["bar"] would actually be equal to foo.bar.