Is Angular usable in Content Script - javascript

I have a Google Chrome extension that injects a content script on given page of a site. This content script replaces the action bound to a button. When the button is clicked, some HTML elements are added (a foundation popup). I want to use Angular to manage the popup I add to the page. Can I do this ?
Here is sample HTML code that could be added when the button is clicked.
<div ng-app="MyApp">
<div ng-controller="MyCtrl as ctrl">
<p> {{ctrl.sayHello()}} </p>
</div>
</div>
Will this work? (I haven't gotten it to work yet, but I'm still trying) If it works, what if the page already contains another Angular app?
After my HTML insertion, the HTML might look something like:
<html ng-app="PageApp">
<body ng-controller="PageCtrl">
...
...
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
...
</div>
</div>
</body>
</html>
Edit: I have found angular.bootstrap(). So I can launch an Angular module on a given DOM element (my div). I think it could be a good solution. Can I still use it if Angular has already tried to load an ng-app directive and failed? Because it will certainly happen when injecting Angular code, and trying to load a PageApp that is not defined for me.

What #estus is saying is correct, and answered your question. Your code will not work, since "[you] can't have nested Angular apps", in other words an Angular app cannot have another Angular app inside of it, regardless of whether you have access to the source (which you probably do, since you're injecting code).
Suggestions
More radical, but note that most, if not all of AngularJS's functionality can be ported to vanilla JavaScript quite easily, if you ignore the attribute binding. You might have to write more specific and manual code, but this would cut any Angular-related problems out of the picture.
There is a hackish workaround that may allow you to nest some Angular apps, but this also requires access to the source of the page in which you're injecting the code, and some crazy DOM searching and manipulation, which may not be too efficient.

Related

Html not view when i click on view Source on browser

I have a issue with my web application. I have used TypeScript, KnockoutJs and Web Api in the web application development, But when i click on view source of browser i have only get some scripts code not found any html tags. i don't understand how it has behave like that,
Please help me, How can i render its html on view source.
I think Knockout.js is the issue. Please check below link:
Knockout visible binding
Check the data-bind tag, value passed to it must be true for content to be visible.
<div data-bind="visible: myValues().length > 0">
You will see this message only when 'myValues' has at least one member.
</div>

angular, directives not running on content being brought in through json

Sort of a weird problem that I'm not exactly sure what is going on so I will try to be as clear as I can.
I am bringing html content through a json object and placing it in a div. The problem I am having is when I bring html in that runs javascript in through a directive, it does not seem to be running. For example - I'm playing around with this http://cmaurer.github.io/angularjs-nvd3-directives/ , a d3 directive for angular.
If I have the html on the template it works fine - I'm using an example from their page that looks like so -
<nvd3-stacked-area-chart data="exampleData" id="exampleId" showXAxis="true" showYAxis="true" showControls="true" width="700" height="200"> <svg></svg> </nvd3-stacked-area-chart>
This works fine when placed on the page, however when I bring it in through the json, it seems the directive (or angular? ) is not running on it.
For reference the part of the json comes in like this -
'content' : '<nvd3-stacked-area-chart data="exampleData" id="exampleId" showXAxis="true" showYAxis="true" showControls="true" width="700" height="200"> <svg></svg> </nvd3-stacked-area-chart>',
then is bound like this
ng-bind-html="widget.content"
This seems to work fine, if I inspect the element I can see the correct html sitting there. I have a $sce.trustAsHtml inside my controller to make sure it's properly escaped.
So I'm not sure how to approach this issue, because there are no specific errors thrown, so I'm not sure if it's angular, or the directive, or the order of events? Is there a way to re-initialize the d3 directive for example on this once the html content is loaded into the div?
I'm not sure where to begin with this, so I would much appreciate any insight. Thank you for reading!
By the time you load the content received by wire, angular has already finished compiling and linking the page. therefor, you need to tell it to recompile. Have a look at this SO and try to call $compile by hand after receiving the content and placing it in the div: How do I make angular.js reevaluate / recompile inner html?
Keep in mind though that this is rather tricky business and you should really check the security of what you're doing.

other than ng-view page loading

I am using a master page having navigation and ng-view on it, partial pages loading successfully under ng-view and with navigation of master page , but I require to load some isolated page like login.html page but not under ng-view and without master page content during route.
I am new on angular and not sure how to do this, login page loaded every time under ng-view.
Please suggest me any way to do this.
Thanks in advanced.
ng-include is your friend. see doc
here is simple way, but you should go to doc and see that there are extra options as to what can be done onload and if you want to autoscroll or do some kind of animation.
<div ng-include="'somefile.html'">
</div>
The one extra note is that ng-include is given an expression so if you have a static reference you need the extra quotes.
One of the great things about Angular is it is very flexible. Ultimately it will depend on your app and how you work. I'm not exactly certain what you are trying to accomplish but, it sounds like a job for the ngInclude directive as Dan mentioned.
You mention a login.html that excludes navigational and other main page content. Using a modal may be a viable alternative interface decision.
If you have everything built and you only want to hide part of the DOM and be done with it then, nghide or ngShow may be the quickest solution.
If there is a lot of stuff on your index.html you may want to separate those things into partials other than the ones connected directly to your routes, and use ng-include="'path/to/partial.html'" to include them. (The "''" are intentional as it likes a string.) Read the docs and experiment with the plunkr. You can do a lot of cool things with ngInclude, especially if you pay attention to its context.
If you combine the ngInclude directive with ng-switch-when, you could put together something like:
<div ng-switch="routeAction">
<div ng-switch-when="extpage" ng-include="'extraneous.content.html'"></div>
<div ng-switch-when="login" ng-include="'login.partial.html'"></div>
<div ng-switch-default ng-include="'default.tpl.html'"></div>
</div>
Where routeAction is tied to your controler which, is tied to your $route or $location.. depending on how you have things set up.

How to build a widget to embed in third-party websites using AngularJs?

I would like to create a angularjs widget that can be embedded in third-party websites with minimal code such as
<script src=mywidget.js type=...></script>
<div id="mywidgetContainer"></div>
or similar.
I found some resources such as this article for developing a widget using jquery http://alexmarandon.com/articles/web_widget_jquery/.
How would it be done using Angularjs? In what clever ways can angular features such as directives/views etc. be harnessed to this purpose? What are the gotcha's if any? Your thoughts/suggestions/opinions/experiences, please.
You should also keep in mind the possibility that the 3rd party website also uses angular,
and potentially a different version.
Check Multiple versions of AngularJS in one page
This is what seems to have worked for me. In the script I set the innerHTML property of the Container div to the angular view markup code. The key point is to use angular.$bootstrap to manually bootstrap the app after the page load. I did not see any particular value in creating a directive. A directive would need to be part of the view code that would still need to be assigned to the container using innerHTML.

What is the best way to change 'views' with Javascript?

For example, I have profile page and select with 'About', 'Photos', 'Videos' section etc., and I don't want to refresh page each time I change section, I want just to change the content of container with Javascript. Sure it wouldn't be handy to write markup of pages in Javascript file, and my idea would be to write div's of each view and display only one of them:
<div id="about>About content</div>
<div id="photos" style="display: none;">Photos content</div>
However, I think there are better ways to do it, because I don't like keeping hidden views on the page. Also in most cases content in views should be generated by script, so it's looks like job for a template engine, but I'm not sure there are such in Javascript.
So what would be the best way to implement this in Javascript. I hope my idea is clear. Thanks in advance!
Try use mustache it is a template engine for javascript.
Also, you can use AngularJS templates (dynamically loaded into page on demand)
It is very easy to use. (However contains other things you might not want.. but should want ;) )
Use jQuery to fetch for the views whenever the user clicks on a link.
For example, bind the click event:
$('#clickToSeePhotos').click(function(){
$('#photosContainer').load('pathTo/photos.html');
});
$('#clickToSeeAbout').click(function(){
$('#aboutContainer').load('pathTo/about.html');
});
Here is the html:
<a id="clickToSeePhotos" href="#">Photos<a/>
<div id="photosContainer"></div>
<a id="clickToSeeAbout" href="#">About<a/>
<div id="aboutContainer"></div>
Here is a link to jQuery's page where they provide more info and examples for load
http://api.jquery.com/load/
You may download the jQuery library and use it on your server. However, as #Cybrix suggests you can also point to the library hosted by Google. See this link. At the end this could improve performance for your users.

Categories

Resources