I am new to AngularJs and working on a website.
I am retrieving the data from Rest services in a page,I am able to display the data using ng-repeat. But the problem is I have a normal javascript functioning element in the page. It is not working when i include the angularjs(ng-repeat). Suggest me to work on it.
Well nowhere up above do we see anything about ng-repeat, however I can tell you its probably got to do with the fact that you're binding your click event on dom ready, and then angular is changing your elements which nullifies the click listener. If you're using ng-repeat, you should be using ng-click as the handler for those events within your controller. Angular takes care of binding the handler specified using ng-click at the proper time when the element exists in the dom. jQuery really has no place in this if you are trying to use angular.
Related
I have buttons that i bind to an event click in jquery :
$('myselection').click(myfunction);
Should they be in the controller ?
I was thinking so but i encountered a situation that made me doubt. In my js view, i create a form and its submit button. I need to attach an event listener to it such as :
$('mybutton').click(myfunctiontosubmit);
I can't figure a way to let the controller manage this listener because the button does not exists when i first call my view.
Usually not. Their place is in the views, however they could call methods in controllers.
Ember.js has the following description for it's Views.
Ember.View is the class in Ember responsible for encapsulating templates of HTML content, combining templates with data to render as sections of a page's DOM, and registering and responding to user-initiated events.
As well as having a simplified API to use said events in the view.
Background
I've been working with Polymer for a while. I've been converting from .5 and building new elements for a production app. We are currently using Polymer 1.0.6, and this particular issue is also using jQuery 2.x.x and typeahead.js.
Issue
We have an element that builds a dynamic list of label and inputs provided by a data source. in the ready function we get a list of input data, and set that to a local list variable that is bound to a foreach template to create the labels and inputs.
I was unable to find a Polymer element I really liked for typeahead, for Polymer 1.0. So I defaulted to using typeahead.js. my problem is that I cannot find a lifecycle event or workaround, to call the typeahead function after the dom has processed setting the bound list in the ready function.
Code
The easiest way to demonstrate this issue, was to create a HEAVILY trimmed down version in a jsbin. I know the element looks bad, it was cut down as much as possible to demo the core issue I'm facing.
http://jsbin.com/zivano/edit?html,output
What Have I Tried?
I've tried using the attached event, and while it does process after the ready function, the dom changes from ready have not taken effect. I found similar issues on SO domReady vs ready - Migrating to Polymer 1.0 I've tried both suggestions, the second is still being used in the jsbin, without success.
I have also bound the click event of my inputs to a function calling the typeahead setup code, to prove that if the calls are made after the dom is rendered it will work correctly.
Summary
If update a data bound, local variable in the ready function, is there a lifecycle event I can call that will guarantee that those dom changes will be rendered, so I can make a dom query against those new items? Or is there a work around that will let me call a js function on a dom element, one time after the element dom fully renders?
my problem is that I cannot find a lifecycle event or workaround, to
call the typeahead function after the dom has processed setting the
bound list in the ready function.
I think I had a problem like this . For my problem I found a solution using the following :
var self = this;
window.addEventListener('WebComponentsReady', function(e) {
// imports are loaded and elements have been registered
/*Example*/
console.log('Components are ready');
var p = self.getElementsByTagName("paper-item");//paper-item created dynamically
console.log(p);//can access and use this paper-item
/*Finish example*/
//here you can call typeahead because the dom has been processed
});
Sorry for my English or if I dont understand your question, my English is bad.
The Issue I had was that the data-bound list was populated through an ajax function, which was completed after the attached function, even if I made an async call inside of the attached function, it would still fail because of race conditions.
It's worth noting the answer by Flavio Ochoa, will work. I personally preffered to not have my custom elements add listeners to the Window. So i went a different route.
Since my issues we're predicated on guaranteeing that the bound list was updated, I wrapped the ajax call in a Promise, and added the typeahead init logic to the then statement. That solution appears to be working.
I do have some concerns whether the promise can guarantee that the bound list will have propagated to the DOM by the time the then statement is processed. But so far it has worked consistently. I'll edit this answer if I can prove otherwise.
I understand that the solution will be non-ideal -- I'm working with legacy code and have many constraints.
On a page in my app, the user choose between one of several forms they want to fill out. When selected, we use JQuery to load the selected form into the DOM. In this newly loaded form, we need to use an angular directive, but angular doesn't know that anything has changed (since JQuery handled the state change), so it doesn't recompile the markup that contains our directive.
How can I let angular know that it needs to make another pass through the DOM?
$scope.apply() will trigger a new check of the DOM.
If you use it with no check, it may fire an error inside angular.
You can use it, wrapped into a $timeout(), so that it will be triggered after a current digest (if there was)
$timeout(function(){
$scope.$apply();
});
I want to disable all the functionalities provided by Angularjs, but only after the pages and all components have been loaded fully.For example "ng-click" should not work any more.
I tried to set the "ng-click" attr to null but, it still works when clicked.
Thank you
You can destroy angular app $scope that means it will disable only two way binding of scope variables using $scope.$destroy() method nothing more than that(If you want to disable two way binding on start up load then you need call $destroy() in $timeout).
But the event listener won't get disabled from angular app which are register while angular app is initialized on page. You can only achieve this by maintaining any flag (this is hacky way).
Here is Fiddle which demonstrate what i want to say.
Thanks.
First here's a plunk: http://plnkr.co/edit/2gD0AB. This plunk doesn't seem to work correctly because $scope.$on("$viewContentLoaded") won't fire, but on my machine it works just fine and I hope you get the idea.
What I'm trying to do there is simply move field objects from $scope.fields to $scope.groupFields = [], $scope.listFields = [], $scope.dataFields = [] when dragging them to the appropriate droppable areas. I've manager to do this using jQuery UI and jQuery UI touch punch (just to be mobile safe).
If you drag an element from the fields box to the one of the empty boxes you'll notice nothing happens on the screen besides the field elements hanging around where you left them. But if do a console.log($scope.fields) in the drop event listener you'll notice that all of the field objects are correctly set inside each of the field boxes.
If you click the Add element button then you'll simply trigger console.log($scope.groupFields); and suddenly all the elements appear correctly in their corresponding boxes like intended in the first place.
After pulling my brains out and after searching the internet for some time I found out that $scope.$apply(), called in the drop event after the moveField function, actually fixes my issue.
And I don't understand why. Shouldn't there be a digest already running and updating the view based on what I'm doing in the controller?
Thanks!
Just because the code that handles these jQuery drop events is inside the controller, it doesn't mean it will run under the angularjs scope/word. For those changes to make effect, you will need to force the angularjs app to do a dirty checking on its models. That can be accomplished by calling $apply() or $digest() methods. You should always call one of these methods after handling an jQuery event that changes $scope properties or after a timeout (or interval).