angularJS $ broadcast和$ on

时间:2013-06-05 07:36:48

标签: angularjs angularjs-scope

有没有办法让$ broadcast在初始化阶段将变量传播到$ on?

<div ng-app='test'>
    <div ng-controller='testCtrl'> <span>{{testContent}}</span> 
    </div>
    <div ng-controller="testCtrl2">
        <input type='text' ng-change="updateContent()" ng-model="testContent2" />
    </div>
</div>

var app = angular.module('test', []);
app.factory('sharedContent', function ($rootScope) {
    var standardContent;
    var resizeProportion;
    return {
        setStandardContent: function (newStandardContent) {
            standardContent = newStandardContent;
            $rootScope.$broadcast('updateContent');
            console.log('broadcast');
        },
        getStandardContent: function () {
            return standardContent;
        },
        setResizeProportion: function (newResizeProportion) {
            $rootScope.$broadcast('updateResizeProportion');
        },
    }
});
app.run(function (sharedContent) {
    sharedContent.setStandardContent('haha');
});

function testCtrl($scope, sharedContent) {
    $scope.testContent;
    $scope.$on('updateContent', function () {
        console.log('receive');
        $scope.testContent = sharedContent.getStandardContent();
    });
}

function testCtrl2($scope, sharedContent) {
    $scope.testContent2 = 'test';
    $scope.updateContent = function () {
        sharedContent.setStandardContent($scope.testContent2);
    };
}

示例小提琴:http://jsfiddle.net/jiaming/NsVPe/

当输入发生变化时,跨度将显示该值,这是由于ng-change功能。

但是,在初始化阶段,值“haha”未传播到$ scope.testContent,因此在第一个运行时没有显示任何内容。有没有办法让值“haha”出现在第一个运行时?

谢谢。

3 个答案:

答案 0 :(得分:1)

使用$timeout功能提供一点延迟。只需更新工厂中的代码即可开始工作。

请参考以下代码了解工厂:

app.factory('sharedContent', function ($rootScope,$timeout) {
    var standardContent;
    var resizeProportion;
    return {
        setStandardContent: function (newStandardContent) {
            standardContent = newStandardContent;
            $timeout(function(){
              $rootScope.$broadcast('updateContent');
            },0)
             console.log('broadcast');
        },
        getStandardContent: function () {
            return standardContent;
        },
        setResizeProportion: function (newResizeProportion) {
            $rootScope.$broadcast('updateResizeProportion');
        },
    }
});

答案 1 :(得分:0)

原因是ng-change会在对testContent2标识的模型进行后续更改时触发。当控制器初始化时,为其分配值“test”。 ng-change然后跟踪后续更改 - 初始分配不符合此条件,只有后续更改才有效。

http://jsfiddle.net/vZwy4/ - 我更新了你提供的小提琴。在这里,您可以看到span标记已正确填充数据。

您需要做的不是使用ng-change,而应使用范围的$watch功能。因此,请从输入框中删除ng-change指令,然后删除updateContent方法。而是将其替换为以下代码,其中您观察testContent2模型的更改:

$scope.$watch('testContent2', function () {
    if ($scope.testContent2 === undefined || $scope.testContent2 === null) {
        return;
    }

    sharedContent.setStandardContent($scope.testContent2);

});

您现在可以看到页面加载时出现“测试”(我找不到与“哈哈”有关的内容)这个词。对输入的后续更改也会在span中更新。希望这是你想要的。

答案 2 :(得分:0)

你没有考虑到应用程序的run阶段在控制器初始化之前执行的事情。由于广播的消息不会被缓冲,并且仅在创建消息时正在侦听的侦听器中提供,因此haha值会丢失。

但是,在您的情况下,通过控制器中的少量更改可以很容易地使其工作:

function testCtrl($scope, sharedContent) {
  updateTestContent();
  $scope.$on('updateContent', updateTestContent);

  function updateTestContent(){
     $scope.testContent = sharedContent.getStandardContent();
  }
}

我在这里分叉你的JSFiddle http://jsfiddle.net/y3w5r01d/2/,你可以在控制台上看到每个函数(运行和控制器)的执行。