Angularjs 角度双向装订不';t从iFrame更新窗口事件

Angularjs 角度双向装订不';t从iFrame更新窗口事件,angularjs,iframe,saml,Angularjs,Iframe,Saml,我需要为SAML身份验证解决方案使用iFrame。基本上,我必须在页面上创建一个Iframe,它调用我们的SAML服务。一旦iFrame获取了Auth对象,它就会触发parent.postMessage(authObj),提醒父窗口Auth信息已经返回 我想在angular服务中捕获该对象,并使其可供应用程序的其余部分使用 因为angular应用程序在返回SAML令牌之前很久就启动了,所以我编写的angular Auth服务需要在$window上有一个事件侦听器来处理该令牌。它可以工作,但当服务

我需要为SAML身份验证解决方案使用iFrame。基本上,我必须在页面上创建一个Iframe,它调用我们的SAML服务。一旦iFrame获取了Auth对象,它就会触发
parent.postMessage(authObj)
,提醒父窗口Auth信息已经返回

我想在angular服务中捕获该对象,并使其可供应用程序的其余部分使用

因为angular应用程序在返回SAML令牌之前很久就启动了,所以我编写的angular Auth服务需要在
$window
上有一个事件侦听器来处理该令牌。它可以工作,但当服务更新时,我看不到双向绑定视图的更新。下面是一些代码来说明我在做什么:

角度服务:

angular.module('common.AuthDataModule', [])

.service('AuthDataService', function($window, $rootScope) {
var AuthObj = {};
AuthObj.params = {
  "isAuthorized": false,
  "principal": '',
  "description": '',
  "authorizationToken": ''
};


  function setAttributes(element, attributes) {
    for (var attr in attributes) { element.setAttribute(attr, attributes[attr]); }
  }

  var createIframe = (function () {
    var iframe = document.createElement("iframe");
    setAttributes(iframe, {
      "name": "auth",
      "id": "myFrame",
      "src": "https://my.dev.SAML2AuthService",
      "height": "0",
      "width": "0",
      "border": "0"
    });

    document.body.appendChild(iframe);
  })();

  // Listen to auth iframe message
  var authEvent = function(event) {
      data = event.data;
      if (data.isAuthorized === "true" && data.authorizationToken !== null) {
        AuthObj.params.isAuthorized = data.isAuthorized;
        AuthObj.params.principal = data.principal;
        AuthObj.params.description = data.description;
        AuthObj.params.authorizationToken = data.authorizationToken;
    }
  }
};

$window.addEventListener ("message", authEvent, false);

var getAuth = function() {return AuthObj;};

return {getAuth: getAuth};
});
angular.module("container.WorkspaceCtrl", ['common.AuthDataModule'])
  .controller("WorkspaceCtrl", function ($scope, AuthDataService, $rootScope) {
    $scope.AuthObj = AuthDataService.getAuth();
});
控制器:

angular.module('common.AuthDataModule', [])

.service('AuthDataService', function($window, $rootScope) {
var AuthObj = {};
AuthObj.params = {
  "isAuthorized": false,
  "principal": '',
  "description": '',
  "authorizationToken": ''
};


  function setAttributes(element, attributes) {
    for (var attr in attributes) { element.setAttribute(attr, attributes[attr]); }
  }

  var createIframe = (function () {
    var iframe = document.createElement("iframe");
    setAttributes(iframe, {
      "name": "auth",
      "id": "myFrame",
      "src": "https://my.dev.SAML2AuthService",
      "height": "0",
      "width": "0",
      "border": "0"
    });

    document.body.appendChild(iframe);
  })();

  // Listen to auth iframe message
  var authEvent = function(event) {
      data = event.data;
      if (data.isAuthorized === "true" && data.authorizationToken !== null) {
        AuthObj.params.isAuthorized = data.isAuthorized;
        AuthObj.params.principal = data.principal;
        AuthObj.params.description = data.description;
        AuthObj.params.authorizationToken = data.authorizationToken;
    }
  }
};

$window.addEventListener ("message", authEvent, false);

var getAuth = function() {return AuthObj;};

return {getAuth: getAuth};
});
angular.module("container.WorkspaceCtrl", ['common.AuthDataModule'])
  .controller("WorkspaceCtrl", function ($scope, AuthDataService, $rootScope) {
    $scope.AuthObj = AuthDataService.getAuth();
});
HTML

<pre style="height:250px" class="testinject">
    {{AuthObj.params.authorizationToken | json}}
</pre>

{{AuthObj.params.authorizationToken | json}
我可以调试并看到auth obj正在返回,如果强制执行
$digest
视图将更新。这让我觉得Angular根本看不到变化,所以它从不费心更新视图。我错过什么了吗

来自:

$rootScope.Scope#$apply([exp])

$apply()用于从外部以角度执行表达式 角度框架。(例如,从浏览器DOM事件, setTimeout、XHR或第三方库)。因为我们正在召唤 我们需要的角度框架执行适当的生命周期范围 异常处理,执行监视

如果您查看
$apply()
的伪代码,您会看到它触发了
$digest()
,这就是为什么您自己强制执行
$digest
可以使它工作的原因

function $apply(expr) {
  try {
    return $eval(expr);
  } catch (e) {
    $exceptionHandler(e);
  } finally {
    $root.$digest();
  }
}
尝试类似(未经测试)的方法:


那个未经测试的代码工作得很好。。。非常感谢。这正是我所缺少的。。。谢谢你的文档参考!