Why is the content of an ng-include dynamically loaded template not available via DOM selectors?

与世无争的帅哥 提交于 2019-12-23 12:28:22

问题


Here's a jsfiddle showing the problem: http://jsfiddle.net/yRLKe/5/

One button compiles before injecting to the DOM, the other one injects before compiling. I did both to make sure that how I compile wasn't the cause of the problem.

Whichever button you click, check the console output and you'll see that the actual template's contents are not available when selecting from the DOM.

So the question is firstly why? - why does it behave this way? but most importantly how? - how can I get access to the actual loaded template's HTML via DOM selectors?

Here's the template:

<script type="text/ng-template" id="template1.html">
   <div>This is template 1!</div>
   <div id="test">Hello {{name}}</div>
</script>

Here's the controller:

myApp.controller('MyCtrl', function($scope) {
  $scope.name = 'Superhero';
  $scope.template = {url:'template1.html'};
  $scope.clickButton1 = function(){
    $scope.$emit('buttonClicked1');  
  };
  $scope.clickButton2 = function(){
    $scope.$emit('buttonClicked2');  
  };
});

Here's the directive:

myApp.directive('compileBeforeInsert', function($compile){
  return function(scope, element, attrs){
    scope.$on('buttonClicked1',function(ev){
        var container = $('#container');
        container.html('<div ng-include src="template.url" id="template">test1</div>');
        $compile(container)(scope);
        console.log('before');
        console.log($('#template').html());
    });    
  }
});

This directive outputs "test1" to the console whereas I would expect it to output "Hello Superman!".


回答1:


The dom is not rendered when the output is written to the console. Using $timeout, you can view the rendered content. MANY people say this is a hack. Regardless, it works. Here's what I changed, with the same result in both directives:

//after injecting $timeout in the directive:
  $compile(container)(scope);
  console.log('before');
  console.log($('#template').children().text());
  $timeout(function(){
      console.log('before, in timeout:');
      console.log($('#template').children().text());
  },0)

Here's the fiddle

Also, see this answer and check out the links within.




回答2:


Your compileBeforeInsert definitely can't work, since you're calling compile -> link -> element but doing nothing with the returned element. It's a no-op.

As to why compileAfterInsert doesn't work, I believe that ng-include is always async, even if the content is already locally available. That's why rgill's setTimeout works.

You might want to re-think this approach... the idea of Angular is that it keeps compiling and digesting over and over until things eventually end up in their stable end state. And there may be asynchronous breaks in that path.



来源:https://stackoverflow.com/questions/17505484/why-is-the-content-of-an-ng-include-dynamically-loaded-template-not-available-vi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!