I am trying to call a function using ng-click when dynamical elements are created but with no success so far. Here is my code
$scope.myfunc = function(){
alert("anything")
}
var divtoappend=angular.element( document.querySelector('#slist'));
divtoappend.append("<button class = 'optv' ng-click='myfunc()'>" +mybutton+ "</button>");
...
No error is thrown and nothing happens on click
You have to compile DOM with $compile API, before injecting into DOM tree, like below.
divtoappend.append($compile("<button class = 'optv' ng-click='myfunc()'>" +mybutton+ "</button>")($scope));
By compiling DOM angular will put all HTML level bindings in $$watchers array of $scope to make sure UI is up to date on every digest cycle.
You need to compile the dynamically generated HTML so that it is under the scope of AngularJS.
Just compile inside append method like
divtoappend.append($compile("<button class = 'optv' ng-click='myfunc()'>" +mybutton+ "</button>")($scope));
Before this inject $compile in your controller.
I have created a plunkr see this plunkr link
You need to compile your DOM elements as follow using $compile
$compile(divtoappent)(scope);
Related
I am trying to load custom components using knockoutjs.
Here is my HTML :
<div id="mainDiv"></div>
JS:
$("#mainDiv").append("<my-component-name></my-component-name>");
This appends <my-component-name></my-component-name> after div but does not bind my component to html.
If I use ko.applyBindings(); it throws error "Error: You cannot apply bindings multiple times to the same element."
I am not able to find whats wrong with bindings.
The view is updated, but the bindings are not. You need to do ko.applyBindings on any elements inserted in the HTML after the bindings are applied the first time. It's a lousy solution to apply components after applying bindings. And DON'T mix knockout with jQuery or js DOM manipulation, PLEEEASSE!
Here I got the solution:
var myComp = document.createElement("my-component-name");
$("#mainDiv").append(myComp);
ko.applyBindings({},myComp);
Ko.applyBinding was needed to bind my component in html.
I'm trying to set a directive to my inputs accordingly.
So let's say I have this input:
<input type="foo" id="myinput" maskvalue> </input>
This works fine on my app, the problem is when I try to insert "maskvalue" dynamically using the "setAttribute" it doesn't work, here's what I'm trying to do right now:
element = document.getElementById('myinput');
if(element){
element.setAttribute('maskvalue', "");
}
This code will successfully insert my directive to the dom element, but will take no effect. It seems that is impossible to insert a custom directive to the dom when it was already loaded, am I wrong?
But that's basically the question, how can I insert a directive dynamically to a dom element?
Thanks
Use Angular's $compile command to Angular-ize this. Basically, you need to notify Angular that you have made a change so it can do its magic.
function MyController($scope, $compile) {
element = document.getElementById('myinput');
if (element) {
element.setAttribute('maskvalue', "");
$compile(element)($scope);
}
}
Make sure you do this in an Angular controller that has $compile and $scope injected into it.
I have an Ionic application with an SVG object with many rectangles (e.g. <rect class="info" id="1001" width="20" height="20" transform="translate(40,40)" />). I would like to add an ng-click directive to each of these without going through and manually appending ng-click to each of them.
Currently, instead, I have the following code in the controller:
$(document).ready(function() {
$('#svg').on('click', 'rect.info', dispInfo);
}
This works as needed, but does not seem to be the "Angular" way. Is there a better way of doing this?
I have tried the following which seemed more angular, yet to no avail:
var elems = $('#svg rect.info');
elems.attr('ng-click', 'dispInfo()');
$compile(elems);
This successfully adds the ng-click directive to the proper elements, but they do not fire. Could it be a problem with the way I am calling $compile ?
To be in more angular way, why cant to wrap your svg rectangle with a directive and add ng-click as part of directive template?
The problem I see with your code is, $compile function accepts html template.
You can try the below,
var elems = $('#svg rect.info'),
$parent = elems.parent();
elems.attr('ng-click', 'dispInfo()');
elems = $compile(elems.html())($scope); // pass your scope variable instead of $scope
$parent.empty().append(elems);
I want to generate multiple forms using "ng-repeat" and bind data to the form.
I have already generated the html using angular js directive, but the events are not firing on generated HTML. I think angular js not able to find that HTML into the loaded DOM.
Here is my code on Plunker:
http://plnkr.co/edit/lJsCUqzd1R6xkq1CgXOM?p=preview
After generating the HMTL, I want to submit the form by "ng-submit" directive.
I am using angular js version 1.4.1 and my custom directive is
<div custom-form formfor="eng" formforid="1"></div>
Since you are using isolated scope in your directive, the directive does not have access to parent scope function directly.
What you can do is to pass the reference of the function to call on submit to directive using syntax:
scope: {
formfor: "#",
formforid: "#",
formFn:"&"
},
Then you need to modify the directive usage to
<div custom-form formfor="eng" formforid="1" form-fn="newsForm2()"></div>
The directive template and implementation also need to change.
See my plunkr here http://plnkr.co/edit/Z4tf0Jqi59S8nNLCmH6z?p=preview
I am using a leaflet map with angular and added a legend. To change the appearance of the map I manipulated the DOM after the view has loaded with a $timeout-method. The legend should be clickable to select which items should appear on the map. So I tried to make an alert, when one item in the legend is clicked. For that I changed the item to a button just to be sure. But the button click doesn't work because it doesn't know the method.
Does anybody know how to call a ng-click method on a manipulated DOM object?
Here is some of my code:
controller.js
//initiating of the map happend before
//now loading of the markers and manipulating of the map
function activate() {
projectService.getMarkers(vm, 'projectsData');
bindEventListener();
$timeout( function() {
getLegendElement();
});
}
//manipulating of the legend element to make a button with a ng-click
function getLegendElement() {
var element = document.getElementsByClassName("legend leaflet-control");
element[0].children[0].innerHTML = '<button ng-click="showAlert()">ok</button>';
}
//showing the alert
$scope.showAlert = function(){
$window.alert("foo");
}
Your DOM manipulation SHOULD be moved to a directive. However, if you wanted to keep it in your controller, you need to inject $compile into your controller and invoke it on your dynamically generated html.
function getLegendElement() {
var element = document.getElementsByClassName("legend leaflet-control");
element[0].children[0].innerHTML = '<button ng-click="showAlert()">ok</button>';
$compile(element)($scope);
}
The reason for this is because Angular looks for event bindings that it needs to generate when it first parses your template. Since you are applying a late event that needs binding to html that did not exist when your template was originally parsed, you need to tell Angular to update its understanding of the template. The documentation calls this out:
$compile
Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and
the template together.