Angular指令的控制器初始化两次

时间:2015-10-15 11:37:39

标签: angularjs angularjs-directive ionic-framework ionic angular-ui-router

我有一个基于https://github.com/driftyco/ionic-starter-sidemenu

的项目

我做了一个指令 rsNotification 来处理即将发布的MQTT消息

rsNotification.js

    (function (angular) {
    console.log("*** rsNotification module init");

    var rsNotificationModule = angular.module('rsNotification', ['rsMessenger']);

    var NotificationController = ['$log', '$scope', 'MessengerService', function ($log, $scope, MessengerService) {

        console.log("*** NotificationController init", $scope);
        $scope.badgeCount = 0;

        $scope.$on('rsMQTT.message', function (event, message) {
            $scope.badgeCount++;
            MessengerService.post(message.toString());
        });
    }];

    rsNotificationModule.directive('rsNotification', function () {
        console.log("*** Loading template");
        return {
            restrict: 'E',
            templateUrl: 'templates/rs-notification.html',
            controller: NotificationController
        };
    });

})(angular);

app.js 中,我有 starter 模块的以下配置

$stateProvider
    .state('app', {
        url: "/app",
        abstract: true,
        templateUrl: "templates/menu.html",
        controller: 'AppCtrl'
    })
    .state('app.dashboard', {
        url: "/dashboard",
        views: {
            'menuContent': {
                templateUrl: "templates/dashboard.html",
                controller: 'DashboardController'
            }
        }
    })

// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/dashboard');

...和指令 rs-notification.html

<button class="button button-clear">
    <span class="fa fa-flag-o fa-2x"></span>
</button>
<span class="rs-badge danger" ng-show="badgeCount > 0">{{badgeCount}}</span>

rs-notification 指令用于 ionic-nav-bar

内的 menu.html 模板
<ion-side-menus enable-menu-with-back-views="false">

    <ion-side-menu-content>

        <ion-nav-bar class="rs-header">
            <ion-nav-back-button>
            </ion-nav-back-button>

            <ion-nav-buttons side="left">
                <button class="button button-icon button-clear ion-navicon color-primary-light" menu-toggle="left"></button>
            </ion-nav-buttons>

            <ion-nav-buttons side="right">
                <div>
                    <button class="button button-clear" ng-click="showCart()">
                        <span>{{cartName}}</span>
                        <span class="fa fa-shopping-cart fa-2x color-primary-dark"></span>
                    </button>
                </div>
                <rs-notification></rs-notification>
            </ion-nav-buttons>

        </ion-nav-bar>

        <ion-nav-view name="menuContent"></ion-nav-view>

    </ion-side-menu-content>

    <!-- Left menu... -->

</ion-side-menus>

问题是每个即将发布的消息 rsMQTT.message 事件被触发两次,事实上 NotificationController 被实例化两次你可以在控制台日志中看到:

*** rsNotification module init
*** NotificationController init
*** NotificationController init
*** Loading template

1 个答案:

答案 0 :(得分:1)

ion-nav-buttons元素的内容recompiled为另一个元素,然后注入$ionViewController。因此,您的指令实际上可能被编译(并且控制器被实例化)两次(或更多)。为了解决这个问题,你应该将你的逻辑转移到一个服务中,并将该元素仅作为一个简单的部分。