AngualrJS:为什么组件范围没有绑定?

时间:2016-03-20 18:44:43

标签: javascript angularjs scope components createjs

我遇到了一个问题并创建了JSFiddle to demonstrate

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中似乎只有单向绑定,因为当组件的范围更新时,“Goodbye”永远不会呈现给视图。

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

修改

我应该说setTimeout只是一个例子,在我的实际案例中,我正在尝试为http://www.createjs.com/添加组件 而不是setTimeout我实际上是在向PreLoadJS添加“完整”事件监听器LoadQueue http://www.createjs.com/docs/preloadjs/classes/LoadQueue.html

3 个答案:

答案 0 :(得分:3)

原因是你在setTimeout里面这样做,这不是在角度上下文中。每当您更新角度上下文之外的范围时,您需要通知angular运行摘要以更新视图

Angular提供服务$timeout,为您解决此问题。

尝试:

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

AngularJS $timeout Service API Reference

答案 1 :(得分:0)

使用$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包装器。它返回promises并与AngularJS框架摘要循环集成。

有关详细信息,请参阅accepts_nested_attributes_for

答案 2 :(得分:0)

使用$timeout代替setTimeout将解决您的问题,因为其他答案会提及,但使用$parent绝不是一个好主意。它使您的代码非常脆弱。例如,尝试在{{$parent.msg}}绑定周围添加ng-if并注意它已断开(http://jsfiddle.net/yagn5v0s/

更好的解决方案是使用组件绑定将某些内容传递出组件。 e.g。

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/