Debugging AngularJS views - html

I have AngularJS application. Let's say, index.html has ng-view or ng-include, and inside that I have ng-if or some custom directive. When I look at Chrome F12, I don't even see the included files. If everything goes fine, I can seem some important stuff in ng-inspector (now that batarang is dead).
But what if I need to debug. Maybe I have a complex expression in ng-if, or even if I simple want to get into a complex binding (order.orderline[2].itemname or similar). But how can I put breakpoints in what is essentially HTML, especially if it's dynamically loaded?

Related

Including HTML in Angular application at compile time

I know the question looks like some others I could read but it's not the exact same issue in my opinion.
I have a "loading screen" (small piece of HTML) in my Angular application. This loading screen is present in three places :
When the application is not loaded yet (so inside the tag of the root component in the index.html : <app-root>my loading html</app-root>
When the router inside the root component is not yet ready to display the "final" component. (See answer here for more detail)
In the "final" component itself waiting for some data to be loaded from an HTTP service.
In the second and the third cases the "loading screen" could be in another component. But it's not possible for the first one since another component will only be displayed after the app is fully loaded and we want the first loading screen to be visible as soon the user get the index.html.
So for the moment I have this short "loading screen" HTML duplicated in multiple places.
I don't care if it's duplicated once built and delivered to the user but from a code point of view I want it to exist only once... (You know how it is, when someone will have to change the message it will be forgotten in the other places...)
I could use iframe (or object but W3C advise to use iframe instead) but people here want to avoid it at all cost so I think the code duplication will be preferred to this solution.
I could also have a small JS to do it (like this answer) but it feel wrong to add a "wild js" in an Angular app...
My question is : Do I have a way to include HTML file into another HTML file (like the "include()" in PHP) with some markup (like in this answer about Service Side Include) that could be resolved during the Angular compilation?
I mean the AOT compilation is already checking the HTML template so it could be quite easy...
Thanks in advance!
It's not in the compilation time, but a way to do something similar to what you are asking, is this:
You could have your "loading screen" html code as a component (for instance, app-loading-component), declared and exported inside a Shared Module.
Then, in the component 'X' in which you want to use it, you have to import the Shared Module in the section imports:[] of the module of that 'X' component, and used it in your HTML in the usual way:
<app-loading-component></app-loading-component>

Need to modify dynamic content after rendering without breaking bindings

I have a service which is called after events which trigger page content changes. This service currently inspects all the viewable HTML on the rendered page for key words and then creates links to a glossary where those key words are used. The page content comes from many sources, including various components and external textual data. Initially this was done by finding all the elements and then searching and modifying the nativeElement.innerHTML which works fine on events that trigger a complete page refresh; in components where the text is based on template bindings, those bindings won't update after the innerHTML changes. I know modifying the innerHTML is bad...
I've tried using the root ViewContainerRef, and ViewRef as starting points but don't see way to access all the page content including content in multi-level child components. Additionally some of the content is added via router-outlet. I was hoping to either dynamically modify the templates, or the rendered content while allowing the component to still render the content when data changes and my service to post process again. Some components are from imported libraries, or receive their data directly, so modifying the component source code doesn't seem like the best option.
I found that by temporarily disabling, forcing change detection, then enabling the component on a data change, it would cause the component to be removed and recreated with working bindings. This is not an optimal solution, but did work as an initial fix. I'll attempt to try the above solution.
Using a MutationObserver you can subscribe to changes of text in the document, then you can manipulate the DOM in a way that doesn't break Angular, i.e. don't change the innerHTML of a node, but rather, insert a sibling with the new HTML and hide (don't remove) the original node.
I've written a stackblitz that demonstrates this.
https://stackblitz.com/edit/angular-highlighter2
EDIT I created an Angular library with all the code, see https://www.npmjs.com/package/ngx-html-highlighter

UI5 doesn't work with AngularJS

I have a single page application written in AngularJS. I need to put a UI5 text field there (for testing purposes) that I am using with Declarative Support.
I have 2 files:
index.html
sap.html.
In my index.html I have <div class="mainView" ng-view></div>
and there I inject sap.html into the index.html.
when I write this line in my index.html I see the sap text field:
<div data-sap-ui-type='sap.ui.commons.TextField' id='message' class='my-button' data-value='Hello World'></div>
However, when I put this code in sap.html the text field isn't being shown in the browser.
When I look in the chrome F12 source mode - I see that the UI5 related tag has been evaluted into textbox in the index.html. This doesn't happen in the sap.html (the "injected by angular ng-view" page) - I just see the tag "as is" - the DOM in the injected page was not evaluted.
Why is that happening? Does AngularJS bootstrap or life cycle
interfere with sap boostrap?
Any way to fix it?
I need to use AngularJS because it is a part of an existing app. A re-write of the app is not an option for me.
Thanks
I never came across this scenario and really do not consider this a good solution (but this is my opinion). I wonder why do you expect UI5 to be aware of AngularJS injecting markup dynamically?
However, the documentation shows an example of how to compile dynamically loaded markup. Obviously AngularJS provides an event to listen to reloads of ngView content, maybe it is possible to trigger the compliation there.

ClojureScript google closure code splitting partial loading

I'm coming from a javascript/react/react-router/webpack background to a clojurescript/om environment.
With webpack & react-router it was possible to split my code and only load the javascript needed. E.g. on /login I would only load the js necessary to display the login-page everything else would be left out.
How do I the same with clojurescript/om?
Apparently it's possible to split your code into multiple files: https://github.com/clojure/clojurescript/wiki/Compiler-Options#modules
The question is how do I only load the code necessary to render the current page: /login for example...
With webpack I would manually write require.ensure to asynchronously load the necessary javascript to render a certain page. React Router supports this very well.
Is there any equivalent in clojurescript without making multiple html files and each giving it the right script tag with the splitted code through google closure modules?
Sadly I don't have a concrete example yet, and I agree that webpack and react-router make this really easy. There are some links that may direct you to get it working:
Code splitting: http://swannodette.github.io/2015/02/23/hello-google-closure-modules
Manually adding script tags to html files
Actual docs: https://github.com/clojure/clojurescript/wiki/Compiler-Options#modules
Dynamic loading of cljs modules: https://rasterize.io/blog/cljs-dynamic-module-loading.html
Uses multi-methods for route definitions to dynamically add implementations when loading more code
Dense read, there is no easy tooling regarding this use case right now, but the article has all clues to get it working
I hope this helps. If you get around to implementing this in an OSS example it would be great if you could share the link.

Why symfony2 it rendering the whole page?

I’m working with Symfony2, and I have a base.html.twig view which includes a navbar and a logo. Also I have other views which extend the base.
When I go from one page that extends the base to another one, the whole page is being rendered in Safari even the navbar and the logo, the same when I reload the page.
Firefox works fine.
So, is there any option in symfony2 to force safari browser to reload just what the code says? (I don’t want to ask the user to install or configure anything in his/her computer).
I think I'm looking for something like that (but for Symfony2): Livereload
There are many ways to make an AJAX requests to load only part of the whole page. You can use pure JavaScript or frameworks like jQuery, Dojo, Backbone.js, Ember.js, AngularJS, Spine.js, KnockoutJS, YUI, Batman.js, Closure, Agility.js, Knockback.js, React.JS. You can use any of them. They all contain AJAX-functionality.
But you need not only JS-framework to work with partial loading. You need also to organise your controllers on the server-side. Your controllers must not extend your base.html.twig but send in response only html-part or JSON-object that represent this html-part.