简体   繁体   English

无法将 iframe 元素从指令传递给 Angular 控制器

[英]Can't get iframe element passed to Angular controller from directive

I have an iframe that has an ng-src attribute on it, and I change it frequently.我有一个带有ng-src属性的iframe ,我经常更改它。 Each time that the iframe's src changes, I want to execute a function in my controller AFTER the iframe is fully loaded.每次 iframe 的src更改时,我想在 iframe 完全加载后在我的控制器中执行一个函数。 Additionaly, I want to have the iframe DOM element passed into the function.另外,我想将 iframe DOM 元素传递到函数中。

Right now I'm using a directive from this StackOverflow post .现在我正在使用这个 StackOverflow 帖子中的指令。 The callback fires when the iframe is loaded, and the function in my controller executes;加载 iframe 时会触发回调,并且我的控制器中的函数会执行; but I can't get the iframe DOM element passed in as a parameter.但我无法获取作为参数传入的 iframe DOM 元素。

Here is a demo Plunkr这是一个演示 Plunkr

THE HTML HTML

<div ng-controller='home as main'>
    <h2>My Content Up Here</h2>

    <button ng-click="main.setIframeSource()">Load iFrame Src</button>
    <iframe iframe-onload="main.onIframeLoad(element)" 
      ng-src="{{main.currentIframeSource}}"></iframe>
</div>

THE Javascript Javascript

(function() {
  angular.module('app', [])
    .controller('home', home)
    .directive('iframeOnload', iframeOnload);

  function home() {
    var vm = this;
    vm.currentIframeSource = '';
    vm.setIframeSource = setIframeSource;
    vm.onIframeLoad = onIframeLoad;

    function onIframeLoad(element) {
      console.log(element);
    }

    function setIframeSource() {
      if (vm.currentIframeSource === '' || vm.currentIframeSource === 'iframe2.html')
        vm.currentIframeSource = 'iframe.html';
      else
        vm.currentIframeSource = 'iframe2.html';
    }

  }

  function iframeOnload() {
    var directive = {
      scope: {
        callBack: '&iframeOnload'
      },
      restrict: 'A',
      link: function(scope, element, attrs) {
        element.on('load', function() {
          return scope.callBack(element);
        });
      }
    };

    return directive;
  }
})();

I've tried using $event and passing in this as a parameter to the onIframeLoad function in my HTML, but I can never get a reference to the iframe DOM element.我试过使用$event并将this作为参数传递给我的 HTML 中的onIframeLoad函数,但我永远无法获得对 iframe DOM 元素的引用。

Thoughts?想法?

When you want to pass data to an expression defined in an isolate scope, you need to pass them via an object with named parameters.当您想将数据传递给在隔离作用域中定义的表达式时,您需要通过具有命名参数的对象来传递它们。 See this documentation page .请参阅此文档页面

So theoretically, all you would have to do is change your directive scope.callback(element) to:所以理论上,您所要做的就是将指令scope.callback(element)更改为:

return scope.callBack({element:element});

BUT, Angular is trying to enforce separation of concerns between what you can do in directives and what you can do in controllers.但是,Angular 正试图在指令中可以做什么和在控制器中可以做什么之间强制分离关注点。 You aren't supposed to do anything with raw elements in your controllers so Angular will prevent you from doing what I just wrote and point you to a page like this: Error: error:isecdom Referencing a DOM node in Expression您不应该对控制器中的原始元素执行任何操作,因此 Angular 会阻止您执行我刚刚编写的操作并将您指向这样的页面: 错误:错误:isecdom 在表达式中引用 DOM 节点

If you want to deliberately break the rules and do a workaround, what you can do is wrap the element in your own object and then it will pass through fine (but remember, this is not recommended)如果你想故意打破规则并做一个解决方法,你可以做的是将元素包裹在你自己的对象中,然后它就会通过(但请记住,推荐这样做)

  link: function(scope, element, attrs) {
    element.on('load', function() {
      console.log('in directive iframe loaded',element);
      // bad bad bad!
      var elemWrapper = {theElem:element};
      return scope.callBack({element:elemWrapper});
    });
  }

I created a plunker showing that this works (uncomment the bad part to see the element being passed)我创建了一个 plunker,显示它有效(取消注释不好的部分以查看正在传递的元素)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM