8

有没有办法让 $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/

span 将随着输入的变化显示值,这是由于 ng-change 函数。

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

谢谢你。

4

3 回答 3

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');
        },
    }
});
于 2017-07-24T14:11:24.210 回答
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. 希望这就是你要找的。

于 2013-06-05T09:27:39.530 回答
0

您没有考虑到run应用程序的阶段在控制器初始化之前执行。因为广播的消息不会被缓冲,并且只提供给在消息创建时正在侦听的侦听器,所以haha值会丢失。

但是,在您的情况下,通过控制器中的一个小改动使其工作很容易:

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

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

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

于 2015-07-08T11:50:07.520 回答