ng-click is not working in angular js - html

I am using angular js one of my project and I call "ng-click" function as below
<a ng-click="logout'{{x.ParentEntityId['#text']}}')" target="_blank">{{x.Title["#text"]}}</a>
In "x.ParentEntityId['#text']" value is "7560183E-1C37-40FE-BACC-8A5B5021FBD7"
When my page load I am getting below error.
When I passed static value in logout function it working perfectly. Like as below
<a ng-click="logout('hi')" target="_blank">{{x.Title["#text"]}}</a>
Logout function as below:
$scope.logout = function (item) {
alert('logout' + item);
};
Please let me know if I am missing something.

In ng-click you are in the angular context, so you haven't to use {{}}.
Your ng-click: logout'{{x.ParentEntityId['#text']}}') is syntactically incorrect, missing a (.
It should be like ng-click="logout(x.ParentEntityId['#text'])".

hey man, I think you error is clear, in the ng-click directive as you wrote
&lta ng-click="logout'{{x.ParentEntityId['#text']}}')"...&gt
so, after logout is missing the ( sign for the function and I think you wont need to create an expression {{}} inside the function parameter because on the angular directives you dont need to send the value inside {{}} because it knows it is a variable and it will receive the values as logout('something').
so for example you need to put as below:
&lta ng-click="logout(x.ParentEntityId['#text'])" target="_blank"&gt{{x.Title["#text"]}}&lt/a&gt

Related

How Do I Dynamically Add onclick on a Razor page?

I am iterating through a LARGE list of objects all of which will open the same modal window that will be loaded with dynamic information. To make this work, I create a counter called MenuCounter that I know increments just fine.
That said, I am attempting to wrap a hyperlink around the icons I need to use and the injection of the method keeps pointing to the last value of the MenuCounter.
I first tried this:
...
When I ran into the issue, I tried reducing the code to the following but then the page somehow activates the hyperlink and the modal window appears and will not go away.
...
Can somebody please help me out?
Thank you!
You should apply a lambda expression to the Blazor #onclick directive instead of using the onclick Html attribute, in which case it should call a JS function, which you did not mean.
Note that I've introduced a new directive to prevent the default action of the anchor element: #onclick:preventDefault
Test this code:
#page "/"
<a href="#" #onclick:preventDefault #onclick="#(() => SetupChangeName(MenuCounter))" >Click me...</a>
<div>Counter is #output</div>
#code
{
private int MenuCounter = 10;
private int output;
private void SetupChangeName (int counter)
{
output = counter;
}
}
Note: If you use a for loop to render a list of anchor elements, you must define a variable local to the loop, and provide it as the input to your lambda expression, something like this:
#for(int MenuCounter = 0; MenuCounter < 10; MenuCounter++)
{
int local= MenuCounter;
<a href="#" #onclick:preventDefault #onclick="#(() =>
SetupChangeName(local))" >Click me...</a>
}
otherwise, all the lambda expressions will have the the same value for MenuCounter, which is the value incremented for the last iteration. See For loop not returning expected value - C# - Blazor explaining the issue.
I'm not a fan of onclick attributes, but if you're set on this method, I believe you just need to santize the C# and JS in the same line like this:
...
Adding the quotes will ensure at least an empty string is present for JS, and then you can process it.
Alternative method
Since mixing languages like that is quite frustrating, I find it easier to use data tags, for example
...
And then in your JS file:
var links = document.querySelectorAll('[data-menu-counter]');
links.forEach(x => x.addEventListener('click', /* your function code here */);

How to handle $ctrl. in AngularJS?

I have a Methode from an API. It returns a promise which resolves to an $ctrl(?) object. This objects should contain a measurement and will be updated whenever it receive a new data.
getMeasurements.latest(filter) //only a object to filter through all measurements
.then(function (latestMeasurement) {
$ctrl.latestMeasurement = latestMeasurement;
});
My problem is that I don't know how to work with this data or display it in my html file. How does $ctrl work?
Here the documentation of the API
$ctrl is the view model object in your controller. This $ctrl is a name you choose (vm is another most common name), if you check your code you can see the definition as $ctrl = this;, so basically its the this keyword of the controller function.
So now if you are using $ctrl.latestMeasurement = 'someValue', then its like you are adding a property latestMeasurement to controller function.
Now how to use it in HTML?
To access the latestMeasurement property in HTML your code must have <h1>{{$ctrl.latestMeasurement}}</h1> (H1 tag is just an example.)
Here $ctrl is different from what I explained above on controller part. Here $ctrl is the value used for controllerAs property of the controller. But $ctrl is the default value of the controllerAs property, so your code may not have the controllerAs property defined, so Angular will take default value $ctrl in HTML.
This is where most people gets confused. So let me explain,
Assume in your new controller you have declared your this keyword to variable vm, and you set your controllerAs property to myCtrl, i.e;
controllerAs: 'myCtrl' while defining controller properties.
var vm = this; in your controller function.
In this case in js you have to use vm for setting values, and in HTML you have to use myCtrl. For example,
in JS controller function vm.test = 'Hello world';
in HTML <span ng-bind="myCtrl.test"></span>
The result Hello world will be displayed in your page.
Why $ctrl and not $scope?
The view model object model concept is introduced in AngularJS 1.5, it is actually part of migrating to Angular 2 where $scope no longer exsist. So in 1.5 they introduced new approch but did not removed $scope completely.
Hope the answer helped.
For basic Javascript concepts you can see http://javascriptissexy.com/16-javascript-concepts-you-must-know-well/
For more detailed AngularJS $ctrl concept you can see https://johnpapa.net/angularjss-controller-as-and-the-vm-variable/
I suppose you are toking about this.
In this case, the
$ctrl.latestMeasurement
can means:
$ctrl, the controller where you are running this code. You can change it by $scope for example, and get the same result.
latestMeasurement, the variable where you want to store the last value of the measurement.
To explain my point of view let see the code below
<div ng-app="MeasurementApp">
<div ng-controller="MeasurementController">
<h1>{{latestMeasurement2}}</h1>
</div>
</div>
There you can see a simple angularjs app that shows a variable called latestMeasurement2 in a div and its controller called MeasurementController. Then, to display the value let check your code.
angular.module('MeasurementApp', [])
// creating the controller
.controller('MeasurementController', function(c8yMeasurements, $scope) {
// creating the variable and let it empty by now.
$scope.latestMeasurement2 = "";
// Your code
var filter = {
device: 10300,
fragment: 'c8y_Temperature',
series: 'T'
};
var realtime = true;
c8yMeasurements.latest(filter, realtime)
.then(function (latestMeasurement) {
// The latestMeasurement is where the measurement comes
// Here we just assign it into our $scope.latestMeasurement2
$scope.latestMeasurement2 = latestMeasurement;
});
});
As the documentation says
// $scope.latestMeasurement2 will be updated as soon as a new measurement is received.
$scope.latestMeasurement2 = latestMeasurement;
Hope this helps!

VueJs component names

I'm working in VueJS and i have the following code
<li #click = "selectedComponent = 'appManagment'"><i class="ion-clipboard"></i>Management</li>
so what i try to accomplish is to display the name like {{selectedComponent}}
but as excpected it displays "appManagment" because this is the component that was selected.
So the question is, how to display a different name, for example i want just "Managment" to appear instead of "appManagment".
I'm using it for the navigation menu that displays where the user is located, so any help would be appreciated.
I would create an object like the one below
var prettyNames = {
'appManagment': 'Some very nice name'
}
and then just use it whenever you want to display text which corresponds to the currently selected component. For example
prettyNames[selectedComponent]
You can register a custom filter with the global Vue.filter() method, passing in a filterID and a filter function. The filter function takes a value as the argument and returns the transformed value:
Vue.filter('custom', function (value) {
// add your code to determine
// name based on value here
return newName;
})
Then use your filter on the text:
<i class="ion-clipboard"></i>{{ selectedComponent | custom }}

Create Html local variable programmatically with Angular2

I need to know if there is a way to create HTML local variables programmatically.
I am developing a web app where I have an NgFor loop and I want to be able to assign a local variable to each sub element created by the NgFor.
ie :
<div *ngFor="#elt of eltList" >
<span #setLocalVariable(elt.title)></span>
</div>
setLocalVariable(_title : string){
let var = do some stuff to _title;
return var;
}
The exemple above shows you what I am trying to accomplish and obviously does not work.
Is there a way to achieve this ?
Thank you in advance.
Edit:
After seeing the answers I got (and i thank everyone who took the time to read my question and tried to answer it) i'll explain a bit more why i want it that way.
I will be using : loadIntoLocation() from the DynamicComponentLoader.
That function got as a 3rd parameter a string that refers to an anchors (ie : #test in an html element). Thats why i need to create those local variables with a name equal to the one of my elt.title.
I think local variables (defined with the # character) don't apply for your use case.
In fact, when you define a local variable on an HTML element it corresponds to the component if any. When there is no component on the element, the variable refers to the element itself.
Specifying a value for a local variable allows you to select a specific directive associated with the current element. For example:
<input #name="ngForm" ngControl="name" [(ngModel)]="company.name"/>
will set the instance of the ngForm directive associated with the current in the name variable.
So local variables don't target what you want, i.e. setting a value created for the current element of a loop.
If you try to do something like that:
<div *ngFor="#elt of eltList" >
<span #localVariable="elt.title"></span>
{{localVariable}}
</div>
You will have this following error:
Error: Template parse errors:
There is no directive with "exportAs" set to "elt.title" ("
<div *ngFor="#elt of eltList" >
<span [ERROR ->]#localVariable="elt.title"></span>
{{localVariable}}
</div>
"): AppComponent#2:10
Angular2 actually looks for a directive matching the provided name elt.title here)... See this plunkr to reproduce the error: https://plnkr.co/edit/qcMGr9FS7yQD8LbX18uY?p=preview
See this link: http://victorsavkin.com/post/119943127151/angular-2-template-syntax, section "Local variables" for more details.
In addition to the current element of the iteration, ngForm only provides a set of exported values that can be aliased to local variables: index, last, even and odd.
See this link: https://angular.io/docs/ts/latest/api/common/NgFor-directive.html
What you could do is to create a sub component to display elements in the loop. It will accept the current element as parameter and create your "local variable" as attribute of the component. You will be able then to use this attribute in the template of the component so it will be created once per element in the loop. Here is a sample:
#Component({
selector: 'elt',
template: `
<div>{{attr}}</div>
`
})
export class ElementComponent {
#Input() element;
constructor() {
// Your old "localVariable"
this.attr = createAttribute(element.title);
}
createAttribute(_title:string) {
// Do some processing
return somethingFromTitle;
}
}
and the way to use it:
<div *ngFor="#elt of eltList" >
<elt [element]="elt"></elt>
</div>
Edit
After your comment, I think that you try the approach described in this answer. Here are more details: create dynamic anchorName/Components with ComponentResolver and ngFor in Angular2.
Hope it helps you,
Thierry
You could stick it into the template interpolation since it handles expressions.
<div *ngFor="#elt of eltList" >
<span>{{setLocalVariable(#elt)}}</span>
</div>
setLocalVariable(_title : string){
let var = do some stuff to _title;
return var;
}

Scope's eval returns undefined in an AngularJS directive

Background:
I'm trying to run a callback when something inside the code of a directive in AngularJS happen.
Pertinent code:
HTML:
<img-cropper onselect="updateAvatarData" x="100" y="100" src="{{tempAvatar}}" id="avatarCropper"/>
Controller:
$scope.updateAvatarData = function(c){
alert("¡¡¡Funciona!!!!");
};
Directive:
<<more code up here>>
link: function(scope,element, attr) {
scope.wsId = attr.id+'WS';
scope.pvId = attr.id+'preview';
scope.x = attr.x;
scope.y = attr.y;
scope.aspectRatio = scope.x/scope.y;
scope.previewStyle = "width:"+scope.x+"px;height:"+scope.y+"px;overflow:hidden;";
scope.onSelectFn = scope.$eval(attr.onselect);
<<more code down here>>
The problem is in that last line "scope.onSelectFn = scope.$eval(attr.onselect);". That "scope.$eval(attr.onselect);" returns 'undefined'. The attr.onselect works fine, it returns the name of the function typed on the 'onselect' attribute.
I have made others directives with functions passed via attibutes with no problem, but am unable to find what I am doing wrong here.
Thanks in advance
Why you are doing like this when u can easily use '&' feature available with angular
calling method of parent controller from a directive in AngularJS
Still if you want to call parent function like this then you should be using $parse instead of eval see a very below small example when using
link: function (scope,element,attrs) {
var parentGet = $parse(attrs['onselect']);
var fn = parentGet(scope.$parent);
fn();
},
scope.$eval(attr.onselect) should work.
Here is a working fiddle (tested in Chrome) with a minimal link function:
link: function(scope, element, attr) {
scope.onSelectFn = scope.$eval(attr.onselect);
console.log(attr.onselect, ',', scope.onSelectFn);
scope.onSelectFn();
},
The only other thing I can think of is that since onselect is an HTML attribute, maybe it doesn't work on some other browsers. So maybe try using a different attribute name.
By default, $eval only evaluates the given expression against the current scope. You can pass in a different data object to evaluate against, and in your case it is the parent scope. You should call it like this:
scope.onSelectFn = scope.$eval(attr.onselect, scope.$parent);
See the documentation here