我正在尝试弄清楚如何让 iframe 中的控制器与主页正文中的 angularjs 实例很好地配合使用。
内容采用登录表单的形式,并通过fancybox显示在iframe中。因此,它有自己的文档头,包括一个 angularjs 库包含和一个控制器,它与父级附加到同一模块。我以前让它像这样工作:
/* parent JS */
var $app = angular.module('Checkout', []);
$app.controller('BasketCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
$rootScope.$on('LoginFormCtrl.login', function(e, data) {
var f = function() {
// do something
};
/* Hack 1 - iframe has its own instance and digest cycle so it might be in phase */
$rootScope.$$phase && f() || $scope.$apply(f);
});
}]);
/* iframe js */
$app.controller('LoginCtrl', ['$scope', '$http', function($scope, $http) {
$scope.login = function() {
$http({
href : '/customer/ajax/login',
data : {
emailAddress : $scope.emailAddress,
password : $scope.password
}
}).success(function(data) {
/* Hack 2 - can't broadcast on own root scope because it's separate from parent's */
$('div[ng-controller="BasketCtrl"]').scope().$broadcast('LoginCtrl.login', data);
});
};
}]);
我只是从记忆中写出来的,所以可能会有错误,但这就是它的症结所在。里面有两件肮脏的东西我已经评论过了。我不知道为什么需要这些黑客,直到我意识到它们没有共同的根范围......
无论如何,我已经尝试将登录内容移到服务中,以便我可以与网站的其他部分共享其逻辑,例如:
$app.service('Auth', ['$http', '$rootScope', function($http, $rootScope) {
return {
login : function(emailAddress, password) {
return $http({
// blah blah blah
}).success(function(data) {
$rootScope.$broadcast('Auth.login', data);
});
}
};
}]);
$app.controller('LoginCtrl', ['$scope', 'Auth', function($scope, Auth) {
$scope.login = function() {
Auth.login($scope.emailAddress, $scope.password).success(function(data) {
parent.$.fancybox.close();
});
};
});
因此,问题是因为现在有两个 angularjs 实例,所以有两个 Auth 实例,当从 iframe 内广播事件时,父 JS 不知道它。
我真的没有看到任何解决方案......我认为问题不在于 angularjs 本身,而在于 iframe 的工作方式。
它需要是一个 iframe,因为它内部还有一些导航到其他相关页面,例如忘记密码表单等。我想保持这种灵活性。
我涉足了将其制作为 ajax 而不是 iframe,但将动态内容链接到 angularjs 的范围是一场噩梦。确保 ajax 内容中包含的链接不会更改窗口位置也存在问题......再加上它继承了页面 CSS......它基本上是一罐蠕虫。
有什么想法吗?