我有$ scope.myArray,并且它通过ngModel和表达式{{myArray}}
与输入字段绑定我的问题是当我通过调用changeMyArray()修改myArray时,输入的值没有改变。但表达式{{myArray}}显示新值。
那么,为什么表达式工作但输入字段不起作用?
我有办法,但我想找到更好的方法
var newArr = $scope.myArray;
newArr.push("b");
$scope.myArray = angular.copy(newArr);;
答案 0 :(得分:4)
基本上,我认为你想要做的是将输入绑定到"新条目"范围变量,然后在用户单击"推送到"时将该变量的值推送到数组。这就是我的意思:
$scope.changeMyArray = function() {
$scope.myArray.push($scope.newEntry);
$scope.newEntry = "";
}
<input ng-model="newEntry">
你真正想要的是一种通过文本编辑数组内容的方法,并且从其他地方更新该数组也会更新文本。这实际上非常简单,因为浏览器附带了一个JSON库。
我是通过从一对已知对象开始实现的:
$scope.myArray = [];
$scope.myArrayString = "[]";
这样你可以通过ngModel更新字符串:
<input ng-model="myArrayString">
注意此模型的更改以更新实际数组:
$scope.$watch("myArrayString", function() {
$scope.myArray = JSON.parse($scope.myArrayString);
});
然后更新changeMyArray
函数中的字符串:
$scope.changeMyArray = function() {
$scope.myArray.push("b"); // Or whatever you would like to add here
$scope.myArrayString = JSON.stringify($scope.myArray);
}
变量$scope.myArray
是一个对象,Javascript中的任何对象都可以转换为字符串(大多数复杂对象最终都是无用的"[object Object]"
)。转换为字符串时,数组实际上会显示其内容,因此通过{{myArray}}
将数组绑定到HTML非常简单。
然而,逆向转换并不那么简单。通常,文本输入不能像我们所希望的那样以双向方式绑定到数组。然后,解决方案是使用中间变量来保存字符串值,并使用$scope.$watch
来保持两个值同步。
答案 1 :(得分:1)
所以你似乎想知道为什么当推送到数组时,你的$ watch函数没有做增量。这是因为#watch函数只检查对象引用相等性。
当推送到数组时,引用保持不变。复制数组并在同一变量中再次设置时,引用会更改。
这就是为什么@watchCollection按预期工作的原因,并在推送每个项目时递增。
答案 2 :(得分:0)
我对我的问题有解释。如果我错了,请纠正我,非常感谢。
我的问题: 当$ scope.myArray发生更改时,为什么“myArray”输入字段不会更新(Model不更新View)?
<input ng-model="myArray" id="myArray">
答案是AngularJs ng-model不知道$ scope.myArray已更改。因为ng-model不执行对象的深度监视(而不是字符串或数字),所以它只查找标识的更改或比较对象的引用。
就我而言,$ scope.myArray是集合。因此,尽管$ scope.myArray已通过推送新项目(结构已更改)而更改,但它的引用不会更改。
结果,$ setViewValue()和$ render()从未被调用来更新视图。
<强>解决方案:强>
Sol1:将新项目添加到$ scope.myArray,制作myArray对象的副本,然后再次将副本复制到$ scope.myArray。通过这种方式,对象引用被改变。 AngularJs看到更改并更新视图。
var newArr = $scope.myArray;
newArr.push("b");
$scope.myArray = angular.copy(newArr);
Sol2:创建custome $ watch('email',function(){...}, true )。最后一个参数为TRUE,让Angular执行深度监视。然后,在watch的监听器函数中,我手动设置$ viewValue = newValue并调用ngModelController的$ render()来更新视图。如果我们有Formatters,我们应该在这一步中调用它们。
$scope.$watch('myArray', function(newValue, oldValue) {
if (newValue !== oldValue) {
var ctrl = angular.element(document.querySelector('#myArray')).controller('ngModel');
// Invoke formatter
var formatters = ctrl.$formatters,
idx = formatters.length;
while(idx--) {
newValue = formatters[idx](newValue);
}
ctrl.$render();
}
}, true);