So I'm working on and application that is a terrible mix of MVC and Angular2.
On my Index page we have a partialview loading the angular app. The index page also has all other javascripts links that are needed to get the angular app working.
This all works fine on the first load, but there's an asynchronous call that calls this grid partial view again and replaces the Angular application with <my-app>Loading...</my-app>.
Question
Is there a way in javascript to reload/restart the angular application after this asynchronous call has been made and the html has been replaced?
Index (main view)
<div>
#Html.Partial("Grid")
</div>
Grid (partial view)
<my-app>Loading...</my-app>
Let me know if I need to do a more in depth explanation.
EDIT
My limited knowledge of Angular suggest that there should be a way to re-run the javascripts that are run on the first load. Isn't it that simple? Just run the boot.js again or something similar? I mean the <my-app> tag is already there.
This was already answered in this GitHub issue a while back but I don't think it is valid on angular 4 anymore
Honestly, This is kind tricky but my idea (I didn't try this) is to do the same on the module bootstrapping level
in the main.ts
export var applicationRef;
platformBrowserDynamic().bootstrapModule(AppModule).then((_appRef) => {applicationRef= _appRef}
);
then you can call destroy() on applicationRef and then you bootstrap the app again to reload it.
Related
I cannot include all the things I need an answer to the title, so here is what I concern:
Must a client side framework/lib be required when developing AEM ? If yes what is the best one fits to AEM and easy for development (Angular.js is just the way that I think it is "enough" good and easy for integration).
In case of using angular.js, I have some doubts:
Which is the most outter App (which is initialized with ng-app) and how We load it because AEM component is separated and I can not load most outter in any of them.
IMO, most outter ng-app will be loaded in the template (which is required by all the components, but it is just in theory (I'm not sure about that) and I do not see any example outhere show me how to load JS,CSS files on TEMPLATE creation (not component creation, just for clearly)
Alternative approach, each AEM component will be an separated angular module, and it will bootstraped manually (I'm not sure, too, please help to clarify)
Last but not least, If you have examples (enough complicated, not like hello world) or production project that used this stack (perfect !), please help to let me know, because my biggest concern is "is it possible to do".
Many many thanks in advance !
I am currently using angular JS with AEM successfully.
Which is the most outter App (which is initialized with ng-app) and how We load it because AEM component is separated and I can not load most outter in any of them.
ans: You can create a renderer component for this purpose and make it as an outer app then add the required clientlibs to it. after that you can use the renderers scope as a normal angular application.
IMO, most outter ng-app will be loaded in the template (which is required by all the components, but it is just in theory (I'm not sure about that) and I do not see any example outhere show me how to load JS,CSS files on TEMPLATE creation (not component creation, just for clearly)
ans: Rather than loading it in the template It will pretty easy to add it in the component as a client lib because everything like js / css in AEM we can add it as a client lib
Alternative approach, each AEM component will be an separated angular module, and it will bootstrapped manually (I'm not sure, too, please help to clarify)
ans: Yes you can create a component as an angular application and you can bootstrap it seperately
I have used Angular 1.x with AEM 6.x and created SPA (Single Page Application). Also, created AEM Screens App using Angular 1.x.
There could be many ways to do it, but I have followed the following approach :-
AEM Page template (body tag) with ng-app and added angular dependency for site (clientlib angular 1.x)
Define angular module in your site clientlib(JS) say module.js,
example: var app = angular.module('app', ['ui.router', 'ngAnimate','ui.bootstrap.tpls','ui.bootstrap.modal']);
You can also define state provider for different paths app.config(function ($stateProvider, $urlRouterProvider) {});
Define each component specific module/controller in a specific clientlib(js) file.
example (html): <div ng-controller="LoginCtrl" />
example (client lib(js)) - app.controller('LoginCtrl',
function ($scope) {});
Typically, you may instantiate a Laravel 5.4 view like so:
Route::get('/', function () {
return view('greeting', ['name' => 'James']);
});
Now I want to use jQuery to perform various front-end tasks on HTML elements defined in the view during the life-cycle of that view - on initialize, on render, on destroy.
I suppose another way of asking this question is: how do I get a client-side javascript function to run after a Laravel view has been loaded?
Just stick your JS in the view, the same as you would do with any HTML page.
Then maybe start moving your JS into separate files.
Then maybe start versioning you assets.
Then maybe take a look at Vue.js.
Mick
We have a product that is a widget people load onto their site, which consists of a single JS file that also needs angular to run, so angular is bundled into the JS file.
However, if a site already is using and loading angular themselves, when they load our widget they get an error which kills everything with the following:
WARNING: Tried to load angular more than once
Which makes complete sense since angular was indeed loaded more than once.
What we'd like to do is either of the following:
In our script, rename / namespace angular so it does't conflict with
the host sites already loaded angular, or
Detect if angular is
already loaded, and if so don't load angular ourselves.
To show examples of our code would be difficult since it's spread over about 20 files etc, however it's based off the following angular seed project which uses requirejs to load everything, then we're compiling to a single file: https://github.com/tnajdek/angular-requirejs-seed
Would really appreciate any feedback / tips / solutions
NB This is not a duplicate of any "check if angular loaded correctly" type questions, angular is packaged inside our widget js, the issue comes when angular is also already loaded by the parent page. We need a way to rename angular inside our package.
I'd advise taking a look at this answer, it has to do with a chrome extension running in the same circumstance. The idea here is to separate your loading of angular from the website's, and it assumes that your widget will be loaded after the main content of the page has been loaded.
If you are loading in html content with an ng-app directive or ng-controller, wrap your html content in a container with ng-non-bindable as an attribute.
Angular looks immediately for an element with the ng-app attribute when you load in angular.js. If two ng-apps are present i.e., on your site, and the widget, it will cause errors. Defer the parsing with: window.name = "NG_DEFER_BOOTSTRAP!" + window.name; Then load in your script.
Once your script has loaded, set window.name to '' or whatever it was before.
Individually bootstrap (the term for angular finding an ng-app attribute) your html content using:
var appRoot = document.querySelector('#id');
angular.bootstrap(appRoot, ['angularModuleName']);
And that should do it... Caveat, I have no idea how this would work if your widget Angular is on a different version than the client website, and I've only made it work with extensions, which are a little bit different because they live in their own isolated 'worlds'.
That being said, I feel like this should get people going in the right direction when dealing with this problem.
I have a problem with navigating between web pages using Angular JS. First web page is index.html, next main.html and also exists a myscript.js file and style.css (but the last is irrelevant in this case).
I want to navigate from index.html to main.html by pressing a button, furthermore there are 2 variables to pass from index.html to main.html and I have to load the next web page with ui-router method or with $location variable in the actual window, as replacing index.html but not with traditional method.
How can I do this?
Thanks for answers!
Using ui router is more flexible work with states, if you have index.html inside you should have a ui- view attribute to change view dynamically, so in your script.js file you have to configure your states, partials views and controller per state (if you want , also you may work with resolve data), and to pass data between controllers you could use services or factory.
This tutorial could help you.
Thanks to everybody for answers! :)
The simpliest method was to create 2 divs on the same HTML page - checking a flag value to display divs using ng-show - instead of navigating between pages.
I use require.js to do lazy loading for a Javascript app. I would love to switch to a meteor stack but right now it looks like Meteor sends the whole app (all the templates) through on the initial load. Has anyone had success with require.js and meteor or any other implementation?
You're asking different questions, but certainly they are connected. The first is about loading additional javascript code into your meteor app. Of course you can use thing like requirejs. This should work fine supposing your lazy code is located in the public directory of your meteor project. However, my experience is that requirejs goes mad when the contents of public gets updated often, so for example in the development environment. Maybe it's a matter of customizing the library, but I would rather recommend using some lightweight homebrewed package. Look here, if you need some inspiration.
The second question is about lazy template definition. Each template consists of two parts. The first is its html code, written in handlebars syntax, the second is all the javascript code which you write to define how your template should behave (e.g. helpers, event handlers). The second part is easy, as long as we assume that we already know how to load the lazy code (see the above paragraph) and the template, lets call it myLazyTemplate, is already defined, so basically speaking Template.myLazyTemplate is not undefined. So how to achieve the latter?
To dynamically define a new template you'll need to call
Template.__define__(name, raw_func)
on the client. So the last question is "what is raw_func?". This is a compiled version of your html code which is normally created automatically on the server and then sent down the wire to the client when the app gets loaded (look here to see how it's done in meteor). But we want to do it dynamically, right?
So the idea is to compile the template code manually with a help of the Handlebars.to_json_ast routine. You can feed it with your template html code, and the output is some javascript array that can be sent to the client anytime by the method we've already talked about. The last thing you need to do is to call Handlebars.json_ast_to_func on the client, using the data sent from the server as the only argument. The output produced by Handlebars.json_ast_to_func is the raw_func you can use to produce myLazyTemplate template.
I'm aware that this is only a rough idea, not the whole solution to your problem. I hope this will help you to figure out the final solution on your own.