5

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.

4
  • do you want to create an element or bind a scope item to an existing element? Commented Oct 2, 2015 at 10:50
  • The element is already created and in the DOM, I have a reference to said element. Now I want to create a new scope and attach it to it. Commented Oct 2, 2015 at 11:30
  • so $compile is what you need Commented Oct 2, 2015 at 11:46
  • Hope this helps someone else, this was really hard to find re search terms! Commented Oct 2, 2015 at 17:33

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Could you explain what's happening $compile(innerElem);?
docs.angularjs.org/api/ng/service/$compile basically it compiles the string or html string to into a template and renders you usually also enter the scope you want to link it to the scope so something like $compile(html)(scope)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.