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

时间:2014-11-05 20:53:18

标签: javascript html angularjs iframe callback

我有iframeng-src属性,我经常更改它。每次iframe的src发生变化时,我想在iframe完全加载后在我的控制器中执行一个函数。 另外,我希望将iframe DOM元素传递给函数。

现在我正在使用this StackOverflow post的指令。加载iframe时会触发回调,并且我的控制器中的函数会执行;但是我无法将iframe DOM元素作为参数传入。

这是demo Plunkr

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>

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;
  }
})();

我尝试使用$event并将this作为参数传递给我的HTML中的onIframeLoad函数,但我永远无法获得对iframe DOM元素的引用。< / p>

思想?

1 个答案:

答案 0 :(得分:0)

如果要将数据传递到隔离范围中定义的表达式,则需要通过具有命名参数的对象传递它们。请参阅:https://docs.angularjs.org/api/ng/service/ $ compile#-scope -

因此,理论上,您所要做的就是将指令scope.callback(element)更改为:

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

但是,Angular正在尝试强制分离您在指令中可以执行的操作与您在控制器中可以执行的操作之间的关注点。您不应该对控制器中的原始元素执行任何操作,因此Angular会阻止您执行我刚刚编写的内容并指向您这样的页面:Error: error:isecdom Referencing a DOM node in Expression

如果你想故意破坏规则并做一个解决方法,你可以做的是将元素包装在你自己的对象中,然后它将通过罚款(但请记住,这是推荐)

  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});
    });
  }

我创建了一个plunker,显示它有效:http://plnkr.co/edit/Oj5lkVAPXdjdNmf62YUQ?p=preview(取消注释坏部分以查看传递的元素)