【问题标题】:AngualrJS: Why isn't Component scope binding?AngularJS:为什么不是组件范围绑定?
【发布时间】:2016-07-07 04:32:53
【问题描述】:

我遇到了一个问题并创建了一个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 中似乎只有单向绑定,因为当组件的作用域更新时,“再见”永远不会呈现给视图。

我使用$parent 是否正确?我的范围错了吗?我是否正确处理了嵌入?

编辑

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

【问题讨论】:

    标签: javascript angularjs scope components createjs


    【解决方案1】:

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

    Angular 提供了一个服务 $timeout 来为你处理这个问题。

    试试:

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

    DEMO

    【讨论】:

    • 感谢您的快速回答 - setTimeout 只是一个示例,在我的真实案例中,我正在添加一个事件侦听器,但我想这同样适用于非角度上下文。我将编辑我的问题以添加有关我的实际案例的更多详细信息。
    • 在使用非 Angular 库时有没有办法传递 Angular 上下文?
    • 在外部更新范围时使用$scope.$apply()
    • 啊,好吧 - 所以现在我已经更新了我的小提琴 jsfiddle.net/503jfL34/3 以使用 $scope.$apply(),它现在可以按我的意愿工作了。谢谢
    【解决方案2】:

    使用$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/

    【讨论】:

      【解决方案3】:

      使用$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 Service API Reference

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-31
        • 2014-02-17
        • 1970-01-01
        • 2014-11-18
        相关资源
        最近更新 更多