Why are we NOT supposed to mix DOM code with Angular code? - html

I am designing a master and child grid in which by clicking on a row of the master grid, data in the child grid changes accordingly. To do so, after clicking on a row of the master grid, I call reloadItmes() from the child controller like below:
$("#masterTable tbody").on("click", "tr", function (event) {
event.preventDefault();
jQuery(this).addClass('selected').siblings().removeClass('selected');
angular.element($('#childTable')).scope().reloadItems();
});
However, I found out that mixing DOM code with Angular code is not a good practice, but I don't know what problem this piece of code could cause.

because of the conflicts between angular scope and dom.
actually they are in different time cycles and it is not a good idea to mix them both with each other.
I had this problem and at last I had to call a fake function in angular to force it to read my dom changes and apply them. It is totally a synchronization problem.
so if you could put both code portions into one controller or either do it all in pure js the result would have better performance and it is much easier to expand or understand.

Related

How do I automate tab selection on a website

Here is the website I am trying to access. I dont want the default tab (Day) though, I want to select the Season tab
https://www.eex.com/en/market-data/power/futures/uk-financial-futures#!/2017/05/23
The link appears to be exactly the same whichever tab is chose making differentiation impossible as far as I can tell.
Any help on this would be much appreciated, using whichever programming method and language is appropriate.
Kind Regards
Barry Walsh
The URL does not change since this is an ajax request, which you can see from MarketDataTableAController's getPageData function. You can read about them here https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
Ive inspected your html and you seem to be using angular. On further inpection you can see that the tabs have ng-click="setActiveTab(tab)" attribute on them. So whenever user clicks, this function gets executed. It is a matter of using this function with the appropriate tab object to get the content to change. You for example could put setActiveTab(tab) into your controller init method since setActiveTab() calls the forementioned getPageData() function to update the page.
Also the tab you are looking for is page.tabs[5] ($parent.page.tabs[5] if referring from TabController) since this is the tab with the label of season. Pass that to setActiveTab() and it should show you the season instead.
However this might not be a good solution since the tab array ordering might change. Then you would need to loop over all objects in page.tabs and see if tab.label === "Season" and pass that in the function instead or better yet use the $filter service provided by angular which would look more cleaner.
Your code source also seems to be minimized and its not very easy to read.

Dom-repeat and neon-animatable in Polymer

I have a same problem with use dom-repeat for neon-animatable in Polymer.
So, about my problem. When I dynamic building page, I use dom-repeat for building a certain number of pages. In code that look like
<neon-animated-pages id="views"
class="flex"
selected="[[selected]]"
entry-animation="[[entryAnimation]]"
exit-animation="[[exitAnimation]]">
<template is="dom-repeat" items="{{dataView}}">
<neon-animatable id="{{item.id}}">
<inner-content data="{{item.content}}"></inner-content>
</neon-animatable>
</template>
</neon-animated-pages>
After builded this page, I have a page which contains a certain numbe neon-animatable pages, but after first click on button for view next page , animation don't work, but if click on button more, animation work fine.
So, I can't understand why first animate don't work
If who have some mind about how resolve this problem, I will be grateful
P.S About my observations
When use in static code like this
<neon-animated-pages>
<neon-animatable>page 1</neon-animatable>
<neon-animatable>page 2</neon-animatable>
<neon-animatable>page 3</neon-animatable>
</neon-animated-pages>
Animation it is running the first time
This appears fixed for a future release: https://github.com/PolymerElements/neon-animation/issues/55
Details:
I ran into the same problem and it appears related to timing on when the light DOM children are created.
Short answer: on your custom element add an attached function that sets the selected page.
attached: function () {
this.async(function () {
this.$.pages.select(0);
});
}
Long Answer
When a template dom-repeat is used inside the neon-animated-pages, at the point the web component is initialized it is not able see the details of the light DOM children.
Using static code the tree is seen as:
neon-animated-pages
- neon-animatable
- neon-animatable
- neon-animatable
Using dom-repeat at initialization it looks like:
neon-animated-pages
- template
Because of this when the neon-animated-pages tries to set the selected page it get undefined because it is not able to see the neon-animatable components. These get created later. This behavior is described in the documentation https://www.polymer-project.org/1.0/docs/devguide/registering-elements.html which says
Note that initialization order of may vary depending on whether or not the browser includes native support for web components. In particular, there are no guarantees with regard to initialization timing between sibling elements or between parents and light DOM children. You should not rely on observed timing to be identical across browsers, except as noted below ... This means that an element’s light DOM children may be initialized before or after the parent element, and an element’s siblings may become ready in any order.
As the light DOM children starts getting filled in a call is made to the observer function "_updateSelected" on IronSelectableBehavior, which is the parent of NeonAnimatedPages, to update the selections based on the content updates.
However, NeonAnimatedPages also maintain internal references to identify selected items and uses the observer function "_selectedChanged" to setup references and control animations. Essentially it decides to display an animation based on whether a previous element is selected. Based on the tree above, when this method is called at initialization it cannot see the full tree and it sets previously selected to undefined. As the light DOM is getting populated, this handler is not getting called because the selected value is not changing only the content is changing. The consequence is that while IronSelectableBehavior correctly knows what is selected, NeonAnimatedPages still thinks nothing is selected, and as you make your initial screen change it treats it as an initial load because it thinks nothing is selected and suppresses the animation.
The solution essentially waits for the entire tree to be built and then sets the selected value so that all the event handlers are able to correctly see the light DOM children and set up internal references.
As Ade mentioned, this was a logged issue in neon-animation, but it has since been fixed. Update the component (bower update, if you're using bower) to resolve the issue. I would have added this as a comment to Ade's answer, but I don't have enough reputation yet

Problema with ng-click function

I am trying to make a product configurator for a website. I'm using MEAN but at this point I just have a problem with AngularJS.
I proceed to explain my program. In the application you have three buttons for the first step of the configuration.
When you click one, AngularJS send back to the web the next three buttons (the values of this buttons depends on the first one you click). And here arrives the problem, this last buttons doesnt seems to work.
After clicking the first button I call the function $scope.getOption2 and it returns this:
htmlsString= '<div><button id="btnS2-1" ng-click= getOption3(1)>1</button></div>'+
'<div><button id="btnS2-2" ng-click= getOption3(2)>2</button></div>'+
'<div><button id="btnS2-3" ng-click= getOption3(3)>3</button></div>';
And this is the way I print it on screen:
$scope.option2 = $sce.trustAsHtml(pruebaHTML);
But the function $scope.getOption3 is never called when I click in one of those buttons.
I have simplified the code, but the essential part is here. I hope somebody can see my problem.
Appending elements like this is not the Angular way, and is frowned upon. Angular does not know of your new buttons, because you cannot manipulate your DOM in this way. You could $compile your elements again, but maybe you should just have the buttons in your template to begin with, you could show them with ngShow. Maybe better yet, see if there is some directive out there that can do what you want - or roll your own.
Look http://docs.angularjs.org/api/ng.$compile for details on $compile.

Visual Studio 2013 LightSwitch HTML Cascading Dropdowns

I'm currently helping a small team create a HTML LightSwitch business app that has a tier of 4 Cascading dropdowns. These drop downs are linked together just as the common example of when you select your state it filters to cities only in that state. However, the issue that we have run into is that upon changing one of the parent boxes the child box doesn't reset or revert to a blank state. How would it be possible to accomplish, if possible, the clearing the child boxes upon parent change. Im pretty sure we need an OnChange event handler but I'm not sure where to put this in LightSwitch because it creates the code for you.
Any idea's or code snippets that are able to fix this problem would be appreciated.
Thank you in advance for the help,
Jeremy
I think you need a change listener event on page created method screen.addChangeListener("DropDown1",DropDown1Changed);
function DropDown1Changed(e){
screen.findContentItem("DropDown2").value ="";
screen.findContentItem("DropDown3").value ="";
};
I havent tested this code. But, something similar to this should work. This should give you general idea about the solution.
Dont forget to remove the listener.
Use pop-ups based on Queries instead of drop-downs. Make the parameters for your queries optional where necessary. LightSwitch will then update the page definition as selections are made. This is because the binding of the popup data values is done at run-time, whereas the binding for controls rendered when the page loads is static.
Michael Washington gives a pretty good summary of the technique in this article.

Asynchronous view call in backbone.js when model is updated

I'm trying to make a demo application for practicing backbone.js.
In my app architecture I first designed the model and inside it wrote a code for parsing a JSON file and storing those records in localStorage and then populating model's attribute hotelsdata with the first 10 records of localStorage.
And then whenever I'm calling the backbone.view.extend() I'm fetching the data from model object.
Now, what I want to do is whenever my model is updated my view must also be updated from the new values in the model. I've already tried
model.on('change',function())
trigger but when I'm calling the view.render() method on the change event my page is being updated, but during the period of adding of records on the page my scroll is not working.
So, can anyone please suggest some way in which I can call that view.render() method asynchronously so that my page's scroll would not be affected during the pressing time of view.render().
In short when my view is being updated the scrolling of the page must work.
I think you have a problem of, how we can call it?, brutal render :)..
I should see your render() method to confirm it, but I think in your render you are removing from the DOM a big portion of the page and then recreating it again. This could cause your scroll to messup. And there is not any asynchronous behavior that can help you.
You should recreate the subelements of your View one by one to have a sweet scroll feeling.
(Show us your render() method if I'm completely confuse)