I want to load dynamic HTML content via AJAX, then compile it, because it contains angular directives.
I have this class that uses methods that help using angular without being in the scope of an angular controller or directive:
var AngularHelper = (function () {
var AngularHelper = function () { };
/**
* ApplicationName : Default application name for the helper
*/
var defaultApplicationName = "MyApp";
/**
* Compile : Compile html with the rootScope of an application
* and replace the content of a target element with the compiled html
* #$targetDom : The dom in which the compiled html should be placed
* #htmlToCompile : The html to compile using angular
* #applicationName : (Optionnal) The name of the application (use the default one if empty)
*/
AngularHelper.Compile = function ($targetDom, htmlToCompile, applicationName) {
var $injector = angular.injector(["ng", applicationName || defaultApplicationName]);
$injector.invoke(["$compile", "$rootScope", function ($compile, $rootScope) {
//Get the scope of the target, use the rootScope if it does not exists
var $scope = $targetDom.html(htmlToCompile).scope();
$compile($targetDom)($scope || $rootScope);
$rootScope.$digest();
}]);
}
return AngularHelper;
})();
Then I use it after my jQuery successful ajax request:
<!DOCTYPE html>
<html>
<head>
<title>AngularJS Test</title>
</head>
<body>
<div id="contents"><!-- content --></div>
<script src="js/angular.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$.get( "http://fuiba.com/test/index.html", function( data ) {
$("#result").html(data);
AngularHelper.Compile('$("#result")', data);
});
});
</script>
</body>
</html>
But I get this error (see this codepen):
$targetDom.html is not a function
You need to pass a DOM element not a string as a first parameter in AngularHelper.Compile function,
so
AngularHelper.Compile($("#result"), data);
not
AngularHelper.Compile('$("#result")', data);
Related
I am having a problem sending a value of JavaScript variable to Angular js variable. I want to send a value in dataArray variable in JavaScript to Angular js variable $scope.test
html code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="angular.js"></script>
<script type='text/javascript'>
$(document).ready(function () {
// $("#fileUpload").load('test.csv');
$.get("test.csv", function(data) {
alert(data);
var rows = data.split("\r\n");
if(rows.length>0){
alert("inside if");
var firstRowCells = GetCSVCells(rows[0], ",");
var dataArray = new Array();
for(var i=1;i<rows.length;i++)
{
var cells = GetCSVCells(rows[i], ",");
var obj = {};
for(var j=0;j<cells.length;j++)
{
obj[firstRowCells[j]] = cells[j];
}
dataArray.push(obj);
}
$("#dvCSV").html('');
alert(dataArray);
$("#dvCSV").append(JSON.stringify(dataArray));
var myjson=JSON.stringify(dataArray);
//alert(myjson);
}
});
function GetCSVCells(row, separator){
return row.split(separator);
}
});
</script>
</head>
<body>
<div id="container">
Test
</div>
<div ng-app="sortApp" ng-controller="mainController">
<div id="dvCSV" ng-model="dataf" ng-bind="bdc">dfsgdfd</div>
</div>
<script src="app.js"></script>
</body>
</html>
app.js:
angular.module('sortApp', [])
.controller('mainController', function($scope) {
window.alert("Angular");
window.alert("asdfad"+$scope.bdc);
$scope.test=$scope.dataf;
window.alert($scope.myjson);
window.alert("test"+$scope.test.value);
You can do this all jquery stuff in angular using http service of angular js.
For simple http service you can refer this link -
http://www.w3schools.com/angular/angular_http.asp
I agree with previous answer. Also its wrong to use $(document).ready along with using angular framework in you application.
Try something like this:
angular.module('sortApp', [])
.service('loadTestCsv' ['$http', function($http) {
return $http.get('test.csv').then(data => {
// do all data processing you need
return data;
});
}]);
.controller('mainController', ['$scope', 'loadTestCsv', function($scope, loadTestCsv) {
loadTestCsv().then(data => {
$scope.data = data;
});
}]);
I'm trying to make a search request using youtube's API and store the result to a variable inside an AngularJS' controller.
This is my app.js file.
var app = angular.module('myApp', []);
app.controller('myController', ['$scope', function($scope){
this.data = '###';
this.search = function(){
var request = gapi.client.youtube.search.list({
part: 'snippet',
q: 'beatles'
});
request.execute(function(response){
var responseString = JSON.stringify(response, '', 2);
this.data = responseString;
// document.getElementById('response').innerHTML += this.data;
});
}
}]);
function onClientLoad() {
gapi.client.load('youtube', 'v3', onYouTubeApiLoad);
}
function onYouTubeApiLoad() {
gapi.client.setApiKey('blahblahblahblahblahblah');
}
and this is the index.html.
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
</head>
<body ng-controller="myController as c">
<div ng-click="c.search()" class="btn btn-success">
Press me!
</div>
<h2>Result</h2>
<pre id="response"> {{c.data}} </pre>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script src="https://apis.google.com/js/client.js?onload=onClientLoad" type="text/javascript"></script>
</html>
In the html code, there is a press me button which invokes the search() function which makes the request. The javascript console shows that the request was executed successfully.
I store the response result to a variable called data. The problem is that the content of the variable does not change. However, if I store this value inside the .innerHTML of a document element (the classic Javascript way), this works, and the results are shown successfully (this line is currently commented out).
Why response result cannot be stored in a variable that lives outside this function?
Please try like this.
app.controller('myController', ['$scope', function($scope){
var c = this;
c.search = function(){
var request = gapi.client.youtube.search.list({
part: 'snippet',
q: 'beatles'
});
request.execute(function(response){
var responseString = JSON.stringify(response, '', 2);
c.data = responseString;
});
}
console.log(c.data);
}]);
I am assuming gapi.client is not an angular library. The request for search is concluded outside angularjs and hence angular doesn't update scope with new response. You will have to call the digest cycle in callback of request.execute. Something like the following should work:
request.execute(function(response){
var responseString = JSON.stringify(response, '', 2);
this.data = responseString;
$scope.$digest();
});
I hope this helps.
Finally, the solution to the problem was a combination of the two answers above:
var app = angular.module('myApp', []);
app.controller('myController', ['$scope', '$q', function($scope, $q){
var c = this;
c.search = function(){
var request = gapi.client.youtube.search.list({
part: 'snippet',
q: 'beatles'
});
request.execute(function(response){
var responseString = JSON.stringify(response, '', 2);
c.data = responseString;
$scope.$digest();
});
};
}]);
we first need to set the controller itself to a variable with
var c = this;
and then we need to call $scope.$digest() as well to update the c.data value. Now right at the time the button is pressed, the result is shown in the page.
I would like to add a div to my current website.
The div i would like to add should show some json data using angularjs.
My problem is that it does not look like angularjs is working like its supose to when adding html after the page is rendered.
Here is my test:
<html >
<head>
<meta charset="utf-8">
<title>Angular test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
</head>
<script>
var featureInfoMainDivId = 'FeatureInfoMaster';
function initAngularDataFeatureInfo() {
var s = document.createElement('script');
s.type = "text/javascript";
s.textContent =
'var app = angular.module("featureInfoApp", []); ' +
'app.controller("featureInfoCtrl", function ($scope) { ' +
'$scope.firstName = "John" '+
'$scope.lastName = "Doe" ' +
'});';
document.getElementById(featureInfoMainDivId).appendChild(s);
}
function addFeatureInfoDiv() {
var divMain = document.createElement('div');
divMain.setAttribute('id', featureInfoMainDivId);
divMain.setAttribute('ng-app', "featureInfoApp");
divMain.setAttribute('ng-controller', "featureInfoCtrl");
divMain.innerHTML ='<div> {{ firstName + " " + lastName }}</div>';
document.getElementById('appdiv').appendChild(divMain);
initAngularDataFeatureInfo();
}
</script>
<body >
<div id="appdiv"></div>
<button id="btn_load_grid" onclick="addFeatureInfoDiv();">loaddata</button>
</body>
</html>
You are missing two semicolons in
$scope.firstName = "John";
$scope.lastName = "Doe";
If you load the Angular script it looks for ng-app and bootstraps itself. Since you add Angular specific code after the script is loaded, you need to bootstrap Angular manually with:
//after initAngularDataFeatureInfo();
angular.element(document).ready(function() {
angular.bootstrap(document, ['featureInfoApp']);
});
Please remove this line:
divMain.setAttribute('ng-app', "featureInfoApp");
It is not needed if you bootstrap Angular manually. For further bootstrapping info, see: Angular bootstrapping documentation.
Also: Is there a reason why you are using Angular version 1.2.26? Version 1.5.3 is the latest stable build.
Try using Angular directives. you can create a customer directive which will then feed a template of your liking
For some reason it gives me the error:
ReferenceError: random is not defined at Scope.$scope.generateRandom
I dont know what im doing wrong, you can go check out the website im using to do this HERE.
index.html:
<!DOCTYPE html>
<html lang= "en">
<head>
<meta charset="UTF-8" />
<title>Basic Login Form</title>
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script src = "https://rawgit.com/nirus/Angular-Route-Injector/master/dist/routeInjector.js"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-route.js"></script>
<script type="text/javascript" src="script23.js"></script>
</head>
<body ng-app = "app" ng-controller = "app">
<button ng-click = "generateRandom()">Generate Random Number</button>
<br> {{randomNumber}}
</body>
</html>
script23.js:
var app = angular.module('app', []);
app.service('random', function(){
var randomNum = Math.floor(Math.random()*10)
this.generate = function(){
return randomNum;
}
});
app.controller('app' , function($scope){
$scope.generateRandom = function(){
alert("Something")
$scope.randomNumber = random.generate();
}
})
To use service in controller, you need to inject it.
app.controller('app', function ($scope, random) {
I'd recommend you to use following syntax:
app.controller('app', ['$scope', 'random', function ($scope, random) {
See Why we Inject our dependencies two times in angularjs?
Change your controller like this, since you are using the service 'random'
myApp.controller('app', ['$scope','random', function( $scope,random)
{
$scope.generateRandom = function(){
alert("Something")
$scope.randomNumber = random.generate();
}
}])
Here is the working Application
Trying to do below:
(a) Embedded a web browser control inside a winform.
(b) Pass a string data from winform control to webbrowser via Invoking a method in JS.
This JS method further calls the angularJS controller. Call is successful. However, the controller which is used in view does not gets updated.
Snippet below:
Invoking side C# winform snippet:
string testString = "testing";
webBrowser2.Document.InvokeScript("InvokeJSPassingTestString", new object[] { testString });
HTML Side.
<html ng-app="ManagerApp">
<head>
<meta charset="utf-8" />
<title></title>
<script src="Scripts/angular.js"></script>
<script type="text/javascript">
var angularApp = angular.module('ManagerApp', []);
angularApp.controller('ManagerCtrl', ['$scope', function ($scope) {
$scope.customParams = {};
$scope.updateCustomRequest = function (data) {
$scope.customParams.value = data;
alert("$scope.customParams.value :" + $scope.customParams.value);
};
}]);
function InvokeJSPassingTestString(data) {
var dom_el = document.querySelector('[ng-controller="ManagerCtrl"]')
var ng_el = angular.element(dom_el);
var ng_el_scope = ng_el.scope();
var test = ng_el_scope.updateCustomRequest(data);
}
</script>
</head>
<body ng-controller="ManagerCtrl">
Passed parameter from winform to JS to angularJs is as below:
{{ customParams.value }}
</body>
</>
In above snippet - I get the alert but the view {{ customParams.value }} does not gets updated.
Any inputs appreciated.
You code is running outside the angularjs digest cycle, so you need to start a new digest cycle after changing data
$scope.updateCustomRequest = function (data) {
$scope.$apply(function () {
$scope.customParams.value = data;
alert("$scope.customParams.value :" + $scope.customParams.value);
});
};
How to update bindings