I need to create a new angular scope and attach it to a DOM element. I'm modifying a third party control so I don't have the option of just using a directive.
I need to do something like:
... = thirdPartyCallbackfunction(domElement){
var myNewScope = $scope.$new(true);
myNewScope.title = 'Hello';
domElement.scope = myNewScope; //???
}
Also, I've tried adding ng-scope
manually to the DOM element, but ng-inspector shows me that it's not creating a new child scope.
$(domElement).scope();
Gives me the root scope when trying that.
The docs weren't very helpful either.
You should use $compile service.
HTML:
<div ng-app="myApp" ng-controller="myCtrl">
<p> Top scope: {{number}}</p>
<p> Top scope: {{myProp}}</p> <!-- Undefined in the top-level scope -->
<div id = "child">
<p> New scope: {{myProp}}</p>
</div>
</div>
Controller:
angular.module("myApp", []).controller("myCtrl", ["$scope", "$compile", function($scope, $compile){
$scope.number = 35;
var myFunc = function(){
var innerElem = angular.element(document.querySelector("#child"));
var innerScope = $scope.$new();
innerScope.myProp = 55;
var compileFn = $compile(innerElem);
compileFn(innerScope);
}
myFunc();
}]);
$compile
is used to evaluate HTML fragment or DOM element (wrapped in jqLite object). For example, instead of the DOM element, you could have used some html template with inline bindings:
var content = "<ul><li ng-repeat='city in cities'>{{city}}</li></ul>"
var list = angular.element(content); //create jqLite object from the template above;
The next step is to use the $compile
service object, which is a function that returns another function which will then be used to generate the content.
var compileFn = $compile(list);
Once you have the compilation function, you invoke it passing the scope object as the context for the upcoming evaluation, basically linking the element with the scope.
compileFn(scope);
Now bindings/expressions contained within the template will be evaluated using the scope you passed it and update the jqLite object (list
), but there will be no return value, so in this case you would have to manually add the updated list
object to DOM. Hope this clarifies the service a bit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With