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

问题描述 投票:3回答:1

我有一个带有iframe属性的ng-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元素的引用。

想法?

javascript html angularjs iframe callback
1个回答
1
投票

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

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

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

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

[如果您想故意违反规则并采取解决方法,可以将元素包装在您自己的对象中,然后将它顺利通过(但请记住,建议not)] >>

  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(取消注释不良部分以查看正在传递的元素)

© www.soinside.com 2019 - 2024. All rights reserved.