页面上有多个AngularJS应用程序

时间:2014-06-29 17:27:30

标签: angularjs angularjs-scope angularjs-routing

我是AngularJS的一个菜鸟,因此对于愚蠢的问题感到抱歉。

我想要做的是在页面上的两个(或更多)位置使用相同的应用程序。为此,我创建了两个HTML元素,然后使用ng-app绑定了我的应用程序。第一个ng-app将通过angular自动引导,第二个必须手动引导,这就是我所做的。

到目前为止,一切都有效,但是当涉及到路由和位置服务时,我已经碰到了一堵砖墙。 基本上,如果使用$ location服务更改位置,则从ng-app的另一个实例访问route参数会引发异常:" [$ rootScope:infdig] 10 $ digest()迭代达成。 !中止 "

以下是我试图开始工作的代码:

<table>
    <tr>
        <td>
            <div>
                <div ng-app="mod1App" class="mod1">
                    <ng-view></ng-view>
                </div>
            </div>
        </td>

        <td>
            <div>
                <div ng-app="mod1App" class="mod2">
                    <ng-view></ng-view>
                </div>
            </div>
        </td>
    </tr>
</table>


<script>
    var rootScopes = [];
    var syncStarted = false;
    var mod1App = angular.module("mod1App", ["ngRoute"]);
    mod1App.config(function ($routeProvider) {
        $routeProvider
            .when("/", {
                templateUrl: '/temp/main.html',
                controller: 'MainCtrl'
            })
        .when("/edit/:param1", {
            templateUrl: '/temp/edit.html',
            controller: 'EditCtrl'
        })
    });

    mod1App.controller("MainCtrl", function ($route, $scope, $location) {
        $scope.testClick = function (e) {
            if (e) e.preventDefault();

            $scope.param = $route.current.params.param1;
        }

        $scope.testNavClick = function () {
            syncStarted = false;
            $location.path("/edit/" + Math.random());
        }
    });

    mod1App.controller("EditCtrl", function ($route, $scope, $location) {
        $scope.testClick = function (e) {
            if (e) e.preventDefault();

            $scope.param = $route.current.params.param1;
        }

        $scope.testNavClick = function () {
            syncStarted = false;
            $location.path("/");
        }
    });

    mod1App.run(function ($rootScope) {
        rootScopes.push($rootScope);

        $rootScope.$on("$locationChangeSuccess", function (event, next, current) {

            if (syncStarted == false) {
                syncStarted = true;

                for (var i = 0; i < rootScopes.length; i++) {
                    if (rootScopes[i] !== $rootScope) {
                        //synchronizing scopes
                        rootScopes[i].$apply();
                    }
                }
            }
        });
    });

    angular.bootstrap($(".mod2")[0], ["mod1App", "ngRoute"]);
</script>

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我认为角度的体系结构可能会阻止它在角度刷新视图(响应范围的变化)时发生无限摘要错误,这反过来会导致范围发生变化,从而触发另一个摘要循环,因此上...

因此,我会质疑你想要实现的目标是在同一页面上使用多个控制器而不是多个应用程序,或者如果你想在具有独立导航的同一页面上使用不同的视图,那么你可能会看到使用angular-ui ui-router https://github.com/angular-ui/ui-router,允许在同一页面上显示多个ng视图。

答案 1 :(得分:0)

我猜您尝试使用modApp更改$routeProvider的HTML内容,但这可能无法正常工作。

根据我的理解,Angular路由提供程序用于向前移动应用程序状态,并通过URL表示此类状态。在您的特定用例中,如果其中一个应用程序位于main.html,而另一个应用程序位于edit.html,则如何表示URL?

如果你想要的实际上是一个单个应用程序,它有一个功能出现在两个地方(而不是两个应用程序实例),那么我相信使用像指令这样的东西应该更适合这份工作。

app.directive('modApp', function() {
    return {
        restrict: 'C',
        templateUrl: '/directive/mod-app.html',
        scope: {
            // if you want separate state handling for each directive instance
            // you define isolated scope for directive here
        },
        controller: function($scope, $rootScope) {
            // define functions related to your directive here
        }
    };
});

由于它是一个应用程序,因此应用程序状态是全面共享的。使用此方法,您只需将ng-app放在一个位置(html节点),但将指令实例放在两个位置。

<div class="mod-app"></div>

请注意,在JS中定义时,您可以使用camel-case命名您的指令:modApp,而在HTML中,您可以使用CSS类mod-app调用指令。

有关指令的更多信息,您可以从官方指南中阅读: https://docs.angularjs.org/guide/directive