I'm new to Angular.JS and i'm trying to load a controller file dinamically when a content loaded from ng-include is requesting it, i do this way because the page i'm building will have multiple controllers and i rather make the initial page to load fast due to it's size, i am not sure to do this and i thought i would achieve it by just doing:
<script type="text/javascript" src="js/controllers/controllerFile.js"></script>
inside the content loaded.
the controller File is like this
app.controller('parseQuery', function()
{
this.object = 'Enter query and parse.';
this.parse = function()
{
this.object = JSON.stringify(window.getParam(this.query), null, '\t');
};
this.getURL = function()
{
this.query = document.URL;
this.parse();
};
});
the html file calls the controller with ng-controller as it should work. But when the content is loaded, javascript returns an error Argument 'parseQuery' is not a, so nothing works, how can i achieve to load a controller file after application is already bootstraped?
To lazy load your scripts, you'll want to check out an AMD or CommonJS loader. These libraries provide the ability to load scripts on demand.
Dan Wahlin has an excellent blog post detailing how to use RequireJS with angular.
In the 1.3.14 AngularJS recieved support for CommonJS. That will be your best bet.
Related
I have set a razor page as the landing page for my application:
options.Conventions.AddAreaPageRoute("Home","/Home/Index", "");
My pages are all contained in areas, so in order to access them by url more easily I wanted to avoid writing the additional area name, so from Home/Home/page to Home/Index:
options.Conventions.AddAreaPageRouteModelConvention("Home", "/Home/Index", model =>
{
foreach (var selector in model.Selectors)
{
selector.AttributeRouteModel = new AttributeRouteModel
{
Template = new string(selector.AttributeRouteModel.Template.SkipWhile(c => c != '/').Skip(1).ToArray()),
};
}
});
I also modified my app settings:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "Default",
template: "{area=Home}/{page=Index}");
});
I removed all the other mapRoutes, including controller routing, etc.
After I added this snippet I tried accessing the pages by /Home/Index, and it worked, however my js scripts are not loading and thus not functioning. Then I removed the aforementioned option and attempted to access the page by Home/Home/Index and my scripts were still not loading. They do load property if I use the anchors I have set up:
<a class="nav-bar-brand" asp-area="Home" asp-page="/Home/Index">...</a>
The script file is included in the Layout:
<script src="js/site.js" type="text/javascript"></script>
The problem appears to be that the browser is looking for the file in the wrong place, this is the Request URL that the General header contains "https://localhost/Home/Home/js/site.js", while in reality the proper address is "https://localhost/js/site.js", why is this happening and how do I fix it?
<script src="**~/**js/site.js" type="text/javascript"></script>
You must update your code thats. (
/
or
~/
get starting on domain root folder)
My angularjs application basically loads in 4 steps:
main HTML
all scripts and CSS files
$templateCache, let's call it template.html
images
I guess, I should bypass the $templateCache when loading the starting page. But for now, I'd like to start fetching template.html ASAP, i.e., at the same time as the scripts get loaded.
The possibly relevant piece of my code looks like
<script src='//ajax.googleapis.com/.../angular.min.js'></script>
<script src='/my.js'></script>
<link href='/my.css' media='all' rel='stylesheet'/>
Here, my.js contains all my scripts and gets loaded at the same time as angular. Is there something allowing me to fetch template.html in the same way, so it gets put into the browser's cache?
Update
I've tried two prefetching possibilities, both failed:
<link href="template.html" rel="prefetch"/>
and
<iframe class=invisible src="template.html"></iframe>
The first gets cancelled and the second comes too late to be effective.
As the HTML can't be fetch soon enough, the whole script directive is completely pointless.
According to runTarm's suggestion, I ended up generating the Javascript instead. All it takes is
.factory('$templateCache', function($cacheFactory, $http, $injector) {
var cache = $cacheFactory('templates');
cache.put("MY_PAGE_1", "ESCAPED_TEXT_1");
cache.put("MY_PAGE_2", "ESCAPED_TEXT_2");
...
return {
get: function(url) {
var fromCache = cache.get(url);
return fromCache ? fromCache : $http.get(url);
}
};
}
In the escaped text you must honor the 1024 string-literal length limit and escape newlines and double quotes. That's all.
I have Durandal SPA which uses url.config.js file among different views. Bunch of urls to services are stored there.
Code for clarity:
define([], function () {
var serviceBaseUrl = 'http://localhost/Service/api/';
var portalPortalUrl = 'http://localhost/Portal';
});
And whenever I need to deploy my app, or run it with different IIS settings, I need to manually change this urls in code.
What I want:
To store them in Web.config file so I can have different configuration for debug and release modes.
I am using MVC 5 Razor views only for rendering bundles and initial content, all client side logic placed in Durandal folder.
I have only found solutions using ASP.NET ConfigurationManager like so:
function ReadConfigurationSettings()
{
var k = '<%=ConfigurationManager.AppSettings["var1"].ToString() %>'
alert(k);
}
Or, for Razor:
#System.Configuration.ConfigurationManager.AppSettings["myKey"]
It's cool, but not my way.
Maybe it's possible to auto generate my urls.config.js file based on Web.config keys?
Thank you in advance.
If needed, here is my project structure:
- App //Durandal SPA
- Controllers
- Views //Only render initial view
- Web.config
You can use JavaScriptResult
Sends JavaScript content to the response.
Code, Controller Action method
public JavaScriptResult Config()
{
var script = string.Format(#"var configServiceBaseUrl = {0};", ConfigurationManager.AppSettings["var1"]);
return JavaScript(script);
}
In the page header(I would load the file first), You can define:
<script type="text/javascript" src='#Url.Action("Config", "Controller")'></script>
Now configServiceBaseUrl is Global JavaScript variable which you can use anywhere.
So you can use configServiceBaseUrl in url.config.js like
define([], function () {
var serviceBaseUrl = configServiceBaseUrl;
});
Adding to satpal, for SPA application such as angular js
For SPA's, such as angular you can use below code in your index.html as
<script type="text/javascript" src='/Controller/config'></script>
I'd like to inject a couple of local .js files into a webpage. I just mean client side, as in within my browser, I don't need anybody else accessing the page to be able to see it. I just need to take a .js file, and then make it so it's as if that file had been included in the page's html via a <script> tag all along.
It's okay if it takes a second after the page has loaded for the stuff in the local files to be available.
It's okay if I have to be at the computer to do this "by hand" with a console or something.
I've been trying to do this for two days, I've tried Greasemonkey, I've tried manually loading files using a JavaScript console. It amazes me that there isn't (apparently) an established way to do this, it seems like such a simple thing to want to do. I guess simple isn't the same thing as common, though.
If it helps, the reason why I want to do this is to run a chatbot on a JS-based chat client. Some of the bot's code is mixed into the pre-existing chat code -- for that, I have Fiddler intercepting requests to .../chat.js and replacing it with a local file. But I have two .js files which are "independant" of anything on the page itself. There aren't any .js files requested by the page that I can substitute them for, so I can't use Fiddler.
Since your already using a fiddler script, you can do something like this in the OnBeforeResponse(oSession: Session) function
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("MY.TargetSite.com") ) {
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
// Remove any compression or chunking
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
// Find the end of the HEAD script, so you can inject script block there.
var oRegEx = oRegEx = /(<\/head>)/gi
// replace the head-close tag with new-script + head-close
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>console.log('We injected it');</script></head>");
// Set the response body to the changed body string
oSession.utilSetResponseBody(oBody);
}
Working example for www.html5rocks.com :
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("html5rocks") ) { //goto html5rocks.com
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
var oRegEx = oRegEx = /(<\/head>)/gi
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>alert('We injected it')</script></head>");
oSession.utilSetResponseBody(oBody);
}
Note, you have to turn streaming off in fiddler : http://www.fiddler2.com/fiddler/help/streaming.asp and I assume you would need to decode HTTPS : http://www.fiddler2.com/fiddler/help/httpsdecryption.asp
I have been using fiddler script less and less, in favor of fiddler .Net Extensions - http://fiddler2.com/fiddler/dev/IFiddlerExtension.asp
If you are using Chrome then check out dotjs.
It will do exactly what you want!
How about just using jquery's jQuery.getScript() method?
http://api.jquery.com/jQuery.getScript/
save the normal html pages to the file system, add the js files manually by hand, and then use fiddler to intercept those calls so you get your version of the html file
So, I know how to use JS or jQuery, etc., to display a "Loading" message while content is loading. I have created a fairly large webapp with a number of JS dependencies and I want to display a "loading" message while all the scripts are loading.
My head tag has a number of <script src=…> tags in it and I want to display a loading message instantly when the user visits the page, and then remove it when all the scripts are loaded.
What's the best way to do this?
Then use $ajax function of jquery to download this javascript files and the add script element in head tag after downloading completes.
like this:
// display loading message here
$ajax("javascriptfile.js",function(file){
// attach downloaded file to head tag now
});
You probably need to lazy loading of the script. The last example from this Lazy Loading show to load .js via YUI. The code from that example is included below for your reference:
var HelloWorld = {
is_loaded: false,
lazyLoad: function(callback) {
var loader = new YAHOO.util.YUILoader();
loader.addModule({
name: "helloworld",
type: "js",
fullpath: "yui_ex/helloworld.js"
});
loader.require("helloworld");
if (callback) {
loader.onSuccess = callback;
}
loader.insert();
},
sayIt: function() {
var args = arguments;
HelloWorld.lazyLoad(function() { HelloWorld.sayIt.apply(HelloWorld, args); });
}
};
Note that you could possibly load the loading image initially and remove it in the callback function. Reading SO Question JQuery to load Javascript file dynamically, you could also use $.getScript() to do the same thing.
You could also find another example in this link