AngularJS:为什么组件范围没有绑定?
AngualrJS: Why isn't Component scope binding?
我遇到了一个问题并创建了一个 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
添加一个 'complete' 事件监听器到 PreLoadJS LoadQueue
http://www.createjs.com/docs/preloadjs/classes/LoadQueue.html
使用 $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 包装器。它 returns 承诺并与 AngularJS 框架摘要循环集成。
有关详细信息,请参阅 AngularJS $timeout Service API Reference。
原因是您在 setTimeout
中执行此操作,而不是在 angular 上下文中。任何时候您在 angular 上下文之外更新范围时,您需要通知 angular 到 运行 摘要以更新视图
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>
我遇到了一个问题并创建了一个 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
添加一个 'complete' 事件监听器到 PreLoadJS LoadQueue
http://www.createjs.com/docs/preloadjs/classes/LoadQueue.html
使用 $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 包装器。它 returns 承诺并与 AngularJS 框架摘要循环集成。
有关详细信息,请参阅 AngularJS $timeout Service API Reference。
原因是您在 setTimeout
中执行此操作,而不是在 angular 上下文中。任何时候您在 angular 上下文之外更新范围时,您需要通知 angular 到 运行 摘要以更新视图
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>