我有这段代码:
<!DOCTYPE html>
<html ng-app="m1">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body>
<div ng-controller='c'>
<input ng-model='x1'><br>
<span>{{x2}}</span>
</div>
</body>
<script>
var m = angular.module("m1", []);
m.controller('c', function($scope){
$scope.x2 = $scope.x1;
});
</script>
</html>
当我在输入框中输入内容时,我看不到它会反映在{{x2}}
输出中。
但是当我通过一个函数执行它时,它可以工作:
<!DOCTYPE html>
<html ng-app="m1">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body>
<div ng-controller='c'>
<input ng-model='x1'><br>
<span>{{x2()}}</span>
</div>
</body>
<script>
var m = angular.module("m1", []);
m.controller('c', function($scope){
$scope.x2 = function(){
return $scope.x1;
}
});
</script>
</html>
为什么这种情况不起作用?在摘要周期中,不应该x2
更新吗?
答案 0 :(得分:5)
当我在输入框中输入内容时,我看不到它会反映在{{x2}}输出中
这是因为x1
或x2
是普通文字,而在Javascript中,文字不是通过引用传递的,而是对象。因此,如果您创建了一个引用该值的对象,它可能会起作用。例如:
var m = angular.module("m1", []);
m.controller('c', function($scope) {
$scope.x1 = {myModel: ''};
$scope.x2 = $scope.x1;
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<div ng-app="m1" ng-controller='c'>
<input ng-model="x1.myModel">
<br>
<span>{{x2.myModel}}</span>
</div>
&#13;
上述方法有效,因为x1
是一个对象,当您将其分配给x2
时,它的引用会被传递,因此两者都是相同的。当您使用x1
作为普通文字字符串时,情况并非如此。
使用angular.copy
克隆或复制对象时,上述操作将无效。看一个相同的例子:
var m = angular.module("m1", []);
m.controller('c', function($scope) {
$scope.x1 = {myModel: ''};
$scope.x2 = angular.copy($scope.x1);
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<div ng-app="m1" ng-controller='c'>
<input ng-model="x1.myModel">
<br>
<span>{{x2.myModel}}</span>
</div>
&#13;
这是因为现在你实际上并没有通过引用传递,但你实际上是在克隆对象。现在,这与你的第一个问题相同。您只是在初始化控制器时将值从x1
复制到x2
,而不是在x1
中的值被修改时。{/ p>
但是当我通过一个函数执行它时,它可以正常工作
当你使用函数时,它是有效的,因为它是Angular的一个功能,当你在Angular中编写一个范围函数并在你的视图中使用它像{{x2()}}
那么 Angular将自动更新视图函数的返回值(本例中为x2()
)已更改/更新。
其他人已经提到过这个问题有多种解决方案。
$watch
(https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope#$手表)
var m = angular.module("m1", []);
m.controller("c", function($scope) {
$scope.$watch("x1", function(newValue) {
$scope.x2 = $scope.x1;
});
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<div ng-app="m1" ng-controller='c'>
<input ng-model="x1">
<br>
<span>{{x2}}</span>
</div>
&#13;
ng-change
(https://docs.angularjs.org/api/ng/directive/ngChange)
var m = angular.module("m1", []);
m.controller("c", function($scope) {
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<div ng-app="m1" ng-controller='c'>
<input ng-model="x1" ng-change="x2 = x1">
<br>
<span>{{x2}}</span>
</div>
&#13;
通过这种方式,您不需要任何Javascript代码。
使用object而不是像我上面提到的普通字符串文字来避免这个问题。
使用Angular的功能功能,如您在问题中已提到的那样。
答案 1 :(得分:1)
您还可以使用观察者:
var m = angular.module("m1", []);
m.controller('c', function($scope){
$scope.$watch(function() { return $scope.x1; },
function(newValue, oldValue) {
$scope.x2 = $scope.x1
}
);
});
这样,x2将在x1的同时更新。
答案 2 :(得分:0)
因为一旦定义了控制器,x1
仅被分配给x2
一次。要查看x2
已更新,您需要将ng-change
指令添加到input
,这将触发将x1
分配给x2
的函数:
<body>
<div ng-controller='c'>
<input ng-change="changed()" ng-model='x1'><br>
<span>{{x2}}</span>
</div>
</body>
<script>
var m = angular.module("m1", []);
m.controller('c', function($scope){
$scope.changed = function() {
$scope.x2 = $scope.x1
}
});
</script>