AngualrJS:为什么组件范围不绑定

AngualrJS: Why isn't Component scope binding?

本文关键字:绑定 范围 组件 为什么 AngualrJS      更新时间:2023-09-26

我遇到了一个问题,并创建了一个JSFiddle来演示

var myApp = angular.module("myApp", []);
myApp.component("bar", {
    transclude: true,
    template: '<div ng-transclude></div>',
    controller: function ($scope, $element, $attrs) {
                        $scope.msg = "Hello";
            setTimeout(function(){
                $scope.msg = "Goodbye";
                alert($scope.msg);
            }, 3000)
    }
});

.HTML:

<body ng-app="myApp">
    <bar>
        {{ $parent.msg }}
    </bar>
</body>

如您所见,我有一个范围变量 (msg),我在完成一些工作后正在更新它(在本例中为 setTimeout)。HTML 中似乎只有单向绑定,因为当组件的范围更新时,"再见"永远不会呈现到视图中。

我使用$parent是否正确?我的范围都错了吗?我是否正确处理了隐含?

编辑

我应该说setTimeout只是一个示例,在我的现实世界中,我正在尝试为 http://www.createjs.com/添加组件我实际上没有setTimeout而是将"完整"事件侦听器添加到PreLoadJS LoadQueue http://www.createjs.com/docs/preloadjs/classes/LoadQueue.html

原因是你在setTimeout内执行此操作,而不是在角度上下文中。每当您在角度上下文之外更新范围时,您都需要通知角度以运行摘要以更新视图

Angular提供了一个服务$timeout,可以为您解决这个问题。

尝试:

controller: function ($scope, $element, $attrs, $timeout) {
        $scope.msg = "Hello";
        $timeout(function(){
            $scope.msg = "Goodbye";
            alert($scope.msg);
        }, 3000)
}

演示

使用$timeout而不是setTimeout可以解决您的问题,正如其他答案所提到的,但使用$parent绝不是一个好主意。它使您的代码非常脆弱。例如,尝试在{{$parent.msg}}绑定周围放置一个 ng-if,并注意到它断开了 (http://jsfiddle.net/yagn5v0s/)

更好的解决方案是使用组件绑定从组件中传递某些内容。

.JS

var myApp = angular.module("myApp", []);
myApp.component("bar", {
    transclude: true,
    template: '<div ng-transclude></div>',
    bindings: {
      msg: '='
    },
    controller: function ($scope, $element, $attrs, $timeout) {
      var self = this;
      self.msg = "Hello";
      $timeout(function(){
        self.msg = "Goodbye";
        alert(self.msg);
      }, 3000)
    }
});

.HTML

<body ng-app="myApp">
    <bar msg="vm.myMsg">
        {{ vm.myMsg }}
    </bar>
</body>

工作解决方案:http://jsfiddle.net/rc8zs4nk/

使用 $timeout 服务而不是原始setTimeout函数。

var myApp = angular.module("myApp", []);
myApp.component("bar", {
    transclude: true,
    template: '<div ng-transclude></div>',
    controller: function ($scope, $element, $attrs, $timeout) {
            $scope.msg = "Hello";
            //Use $timeout
            $timeout(function(){
            //
            //setTimeout(function(){
                $scope.msg = "Goodbye";
                //alert($scope.msg);
            }, 3000)
    }
});

$timeout服务是setTimeout函数的 AngularJS 包装器。它返回承诺并与AngularJS框架摘要周期集成。

有关更多信息,请参阅 AngularJS $timeout服务 API 参考。