4

我有一个主页模板(离子)有一个像这样的标签:

<ion-tab title="ACCOUNT" icon="ion-trophy" href="#/home/account" badge="levelBadge" badge-style="badge-assertive" on-select="enteringAccount()" on-deselect="leavingAccount()" ng-controller="homeTabCtrl">
            <ion-nav-view name="tab-account" animation="slide-left-right"></ion-nav-view>
        </ion-tab>

当其他范围内发生某些事情时,我希望更改 levelBadge 值。

在其他范围内,我有这个控制器(lessonCtrl)。当单击此视图上的按钮时,控制器会在此控制器内调用此函数:

$scope.testBoardcast = function() {
        MyFirebaseService.testBoardcast();
}

在 MyFirebaseService (工厂)中,我有这个功能:

function testBoardcast() {
        $rootScope.$broadcast('level-up', 2);
}

在我的主模板 homeTabCtrl 中,我正在听这样的升级事件:

$rootScope.$on('level-up', function(event, data) {
        console.log ("App received level up boardcast: " + data);
        $scope.levelBadge = parseInt(data, 10); 
    });

但问题是,当我单击 courseCtrl 上的按钮时,levelBadge 没有得到更新,并且即使在我单击按钮后立即显示控制台日志“App received level up boardcast:”也不会显示徽章。

如果我像这样只听 homeTabCtrl 范围:

$scope.$on('level-up', function(event, data) {
        console.log ("App received level up boardcast: " + data);
        $scope.levelBadge = parseInt(data, 10); 
    });

当我单击课程Ctrl 上的按钮时,什么也没有发生。

我不知道如何使 levelBadge 在我在课程Ctrl 中单击处于完全不同状态的按钮时动态更改。

更新:这是我的 ui-route:

.state('home', {
  cache: false,
    abstract: true,
    url: "/home",
    templateUrl: "app/home/home.html",
  controller: 'homeTabCtrl',
  onEnter: function($state, MyFirebaseService) {
    var userId = MyFirebaseService.LoginUserId();
    if (!userId) {
        $state.go('auth.signin');
    };
  }
})

.state('home.courses', {
  cache: false,
  url: "/courses",
  views: {
    "tab-courses": {
      templateUrl: "app/home/courses.html"
    }
  }
})

.state('app', {
    abstract: true,
    url: "/app",
    templateUrl: "app/layout/menu-layout.html",
  controller: 'AppCtrl'
})

.state('app.lesson', {
  cache: false,
  url: "/lesson/:id",
  views: {
    'mainContent': {
      templateUrl: "app/all/lesson-detail.html",
      controller: "lessonCtrl"
    },
  }
})

所以家是一个抽象的状态。选项卡位于主模板中。courseCtrl 实际上处于另一个称为 App 的抽象状态。它们不是合作伙伴或子范围。只有2个不同的范围。

4

1 回答 1

3

我需要查看您的 ui-router 配置 ($stateProvider) 以进一步调试您的代码未按预期工作的原因。这很可能是由于在调用 $broadcast 时未实例化 homeTabCtrl。

一种解决方案是使用服务。对服务进行更改,然后在 homeTabCtrl 中监视该服务。

在您的课程控制器调用中

Level.levelUp(1);

然后在你的 homeTab 控制器中观察 Level 服务的变化

$scope.$watch(
  function () {
    return Level.currentLevel();
  },
  function(newVal, oldVal) {
    $scope.level = newVal;
  }
);

这是一个设置此结构的 plunker:http ://plnkr.co/edit/mAASNGNqr37k9n0RR89X?p=preview


编辑

看看这个设置了类似视图层次结构的 plunker:http ://plnkr.co/edit/hyKECbyYAG8XzUh8x58K?p=preview 。请注意,当您导航到应用程序和家庭状态时,控制台日志如何打印初始化消息。

每次从 home 状态更改为 app 状态时,home 控制器都会被实例化,而 app 控制器会被实例化(这个答案在某种程度上解释了流程:angularjs 控制器实例化, ui-router)。

因此,当您转到应用程序状态时,主状态无法监听事件。单例服务将按您的意愿工作,所以我建议使用它而不是 pub/sub 方法。

于 2015-06-12T03:29:15.803 回答