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

Posted

技术标签:

【中文标题】无法将 iframe 元素从指令传递给 Angular 控制器【英文标题】:Can't get iframe element passed to Angular controller from directive 【发布时间】:2015-01-02 05:11:51 【问题描述】:

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

现在我正在使用来自this *** 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 元素的引用。

想法?

【问题讨论】:

【参考方案1】:

当您想将数据传递给在隔离范围内定义的表达式时,您需要通过具有命名参数的对象来传递它们。见this documentation page。

所以理论上,您只需将指令 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);
    );
  

我创建了a plunker showing that this works(取消注释坏部分以查看正在传递的元素)

【讨论】:

那么,如果我想创建一个iframe 指令,允许我在加载后将通用函数传递给 iframe(在它的 onLoad 事件中),推荐的方法是什么? 这是一个不同的问题,但您不能真正将函数传递给 iframe,您需要使用 postMessage 与 iframe 进行通信。 感谢您的反馈。我知道不推荐这种方法。但是,如果我想要一个 iframe onLoad 指令将通用函数传递给 iframe 的 onLoad 事件,我应该如何处理这个?有推荐的方法吗? 具体来说,我想在加载的 iFrame 中找到一个 DOM 元素并更改它的值/类。我讨厌在我的 Angular 中使用 jQuery 的想法,但我不确定是否还有另一种 pure Angular 方式 在你的指令中,你可以添加关于需要做什么的必要逻辑(比如如何找到元素,如何处理它等)。但是,您可以对 iFrame 中的内容实际执行的操作将取决于它是否位于同一域中,或者您是否有权更改网站本身。看到这个***.com/questions/164085/…

以上是关于无法将 iframe 元素从指令传递给 Angular 控制器的主要内容,如果未能解决你的问题,请参考以下文章

语法错误:将变量传递给指令时,令牌“:”是一个意外的令牌

从窗口将值传递给 iframe

如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件

如何将不同的类传递给元素指令

通过属性指令将 CSS 样式传递给子 HTML 元素

将所有指令传递给组件的子元素