The below functions works well.
var el = angular.element('<div>{{ name }}</div>');
elem.append(el);
$compile(el)(scope);
but why does this not work?
var el = angular.element('<div>{{ name }}</div>');
elem.append(el);
$compile(el)({name:'Fred'});
Isn't scope just an object w/name-value pairs?
RESOLUTION:
How to $compile an AngularJS template using a newly created scope?
or resolution in code format
var elS = angular.element($templateCache.get('tmpl/x.html')[1]);
var linkFn = $compile(elS);
var newScope = scope.$new();
newScope.s = scope.sCtrl.s;
var content = linkFn(newScope);
el.append(content);
In angular you write template markup html, which needs to be compiled first before it can be rendered in the browser. $compile converts the template html to DOM html.
Template Html markup usually has variables that are linkable from their originally definition in scope. Those can be linked using $compile. As a end result compile transforms the markup can be rendered in the browser.
Related
I'm trying to render html content from a controller , but the angular directive ng-hide doesn't work , I've tried the following code, does it have a problem with binding as html this way?
var htmlContent = "<Div class='vzone' ng-hide='true' id='parent_" + ViewerZones[CurrentIndex].Id + "'...'></div>";
$scope.PageContent = $sce.trustAsHtml(htmlContent);
<div ng-bind-html="PageContent"></div>
try this one,
var htmlContent = "<Div class='vzone' ng-.....
$scope.PageContent = $sce.trustAsHtml($compile(htmlContent));
don't forget to add $compile dependency in your controller.
$compile service will bind your dynamic directives with the controller
I would like to interact with a scoped inside an appended html element on the page, can someone please show me how to update that scope?
var overlay = angular.element('<div id="flyout-overlay" class="page-overlay global" ng-show="testScope"></div>');
mainContent.append(overlay);
$timeout(function(){
$scope.testScope = true; // how?
},500);
use $compile service
$compile(overlay);
here is the documentation
don't forget to add $compile dependency in the controller
doc says,
apply to your case,
'<div id="flyout-overlay" class="page-overlay global" ng-show="testScope"></div>'
1 : compile - $compile collect all the directives, for ex, it will collect ng-show directive
2: link - combine the directive with a scope.. , for ex, it will bind the ng-show="testScope" directive with the scope.
#Kalhano gave the perfect answer but since you don't know about the $compile service, here is the code for you. Just a small change....
var overlayTmpl = angular.element('<div id="flyout-overlay" class="page-overlay global" ng-show="testScope"></div>');
var overlay = $compile(overlayTmpl)($scope);
mainContent.append(overlay);
$timeout(function(){
$scope.testScope = true; // how?
},500);
in nutshell, $compile service compiles your html and links it to the scope you provided,
for better understanding read the angular documentation.
Question
In AngularJS, is there a way to convert a string template into markup without using scope or a directive?
Explanation
I have a service which allows me to create new angular apps dynamically. It builds up the DOM for the new app, then runs angular.boostrap on the element.
Currently, the DOM is created like this:
var element = document.createElement('div');
element.setAttribute('app', '');
element.setAttribute('size', 'small');
...
element.className = 'app layout--relative';
There are many attributes, classes, child elements, etc, so creating the markup in this way is not ideal. It would be better to use a template.
Normally I would use $compile to convert a string template into markup, but because I have not run angular.bootstrap yet, there is no scope in order to use $compile(template)(scope);
What I have tried
Create a div, then replace the innerHTML with the template string
This works, but all of the attributes and classes on the root element need to be added separately.
var element = document.createElement('div');
element.innerHTML = template;
Remove scope after the template has compiled
This works, but I would prefer to avoid scope altogether:
var scope = $rootScope.$new();
var element = $compile(template)(scope);
scope.$destroy();
You could use the $interpolate service for string substitution like this:
var template = '<div app size="{{size}}" class="{{className}}">' +
'<span>Hello {{name}}!</span>' +
'</div>';
$interpolate(template)({
size: 'small',
className: 'app layout--relative',
name: 'World'
});
and the result would be like this:
<div app size="small" class="app layout--relative">
<span>Hello World!</span>
</div>
Hope this helps.
So I have some html that gets loaded into the #panel div dynamically depending on which questionNumber the user is on. This is not all of the code but all of the relevant code I think. Anyway, the <input> get's loaded into the page but it doesn't actually do anything. what am I missing here? I have the same problem when the questionNumber === 1, where the binded variables just show up as {{variable}} etc
var readingController = function (scope, Romanize){
scope.usersRomanization;
//alert(scope.usersRomanization);
}
var app = angular.module('Tutorials', ['functions', 'tutorials']).controller('getAnswers', function ($scope, $element, Position, Romanize) {
$scope.sectionNumber = Position.sectionNumber;
if ($scope.sectionNumber === 0){
$('#panel').html('<div ng-controller="readingController"><input ng-model="usersRomanization"></input></div>');
readingController($scope, Romanize);
}
<body ng-controller="getAnswers">
<div id="panel">
</div>
</body>
If you add HTML to the DOM, you have to tell Angular to $compile it. This should be done in a directive. You'll need to inject $compile then do something like this:
var content = '<div ng-controller=...></div>';
var compiled = $compile(content)(scope);
// then put the content where you want
Or better, define a directive and use a template, which will automatically get compiled for you by Angular.
Other alternatives are ng-include (which will compile the loaded content for you) and ng-switch, which would allow you to put the templates into the HTML.
I use angular js 1.0.3 and I try to test my directive.
we use jQuery that is loaded automatically by angular and is accessible as angular.element that is passed to directive.
how can I add properties to the element before directive is linked with scope???
var def = '<input data-my-directive="" />';
var scope = $rootScope.$new();
var linked = $compile(def);
// do something to add property something that jq is adding
var directive = linked(scope);
my directive is something like
return function(scope, element, attrs) {
element.jq-plugin-method();
}
and my target is element passed to directive after linkage.
thanks for help
To answer my own question. it is sufficient to add
var jqLite = angular.element;
jqLite.prototype.jq-plugin-method = function(c) {...};
before
linked = $compile(definition);
I was blind or something yesterday or maybe I was adding this line after compile and it was too late.