1

我正在尝试弄清楚如何让 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......它基本上是一罐蠕虫。

有什么想法吗?

4

1 回答 1

0

我基本上是通过将父级的 Auth 服务注入 iframe 的范围来让它工作的。

$app.controller('LoginFormCtrl', ['$scope', function($scope) {
    $scope.auth = parent.$('body[ng-app="Checkout"]').injector().get('Auth');
}]);

它并不完美,而且完全无法测试,但它确实有效,嘿嘿。

于 2013-06-28T09:32:01.280 回答