我在ng-repeat中遇到双向绑定问题。当你从列表中选择一种颜色时,我希望触发下面的$ watch。
$scope.$watch('favoriteColors', function (newValue) {
console.log('example-favoriteColors', newValue);
});
我希望Orange
在$scope.favoriteColors
检查时显示。
示例:http://plnkr.co/edit/k5SEQw4XFnxriD2I8ZG7?p=preview
directive('checkBox', function () {
return {
replace: true,
restrict: 'E',
//require: '^ngModel',
scope: {
'externalValue': '=ngModel',
'value': '&'
},
template: function (el, attrs) {
var html =
'<div class="ngCheckBox">'+
'<span ng-class="{checked: isChecked}">' +
'<input type="checkbox" ng-model="isChecked"/>'+
'</span>'+
'</div>';
return html;
},
controller: ['$scope', '$timeout', function ($scope, $timeout) {
var initialized = false;
console.log($scope.value());
if (angular.isArray($scope.externalValue)) {
$scope.isChecked = $scope.externalValue.indexOf($scope.value()) > 0;
} else {
$scope.isChecked = !!$scope.externalValue;
}
$scope.$watch('isChecked', function (newValue) {
if (angular.isDefined(newValue)) {
//add or remove items if this is an array
if (angular.isArray($scope.externalValue)) {
var index = $scope.externalValue.indexOf($scope.value());
if(index > -1) {
$scope.externalValue.splice(index, 1);
} else if (initialized) {
$scope.externalValue.push($scope.value());
}
} else {
//simple boolean value
$scope.externalValue = newValue;
}
if (initialized)
console.log($scope.externalValue);
}
});
$timeout(function () {
initialized = true;
});
}],
link: function (scope, el, attrs) {
}
};
});
答案 0 :(得分:2)
请查看此插件:http://plnkr.co/edit/pbHz4ohBPi7iYq6uJI8X?p=preview
有很多变化。其中一些是:
initialized
(因此$timeout
)。indexOf
功能; ==
意义上的对象有可能不同,但在x.name === y.name
意义上等于; (虽然我对此有些怀疑)add or remove items if this is an array
部分错了;您需要根据isChecked
的值更新数组,而不是基于项目是否已存在于数组中indexOf
)。favoriteColors
初始化为数组,而不是单个对象,以保持一致,即$scope.favoriteColors = [$scope.colors[1]];
favoriteColors
更改时添加了更多描述性日志。$watch("favoriteColors", function() {...}, true)
来监视数组内的更改(而不是true
最后一个参数)。答案 1 :(得分:0)
我认为这是因为您需要在对象而不是平面数组上引用属性。传递像数组一样的原始数据结构时,它会通过引用传递,因此更新不会正确传递。 (Post by Mark Rajcok.)
我继续前进并通过一点点攻击你的傻瓜来证明这一点。我将$scope.favoriteColors = $scope.colors[1];
更改为$scope.favoriteColors = {value:$scope.colors[1]};
并将<check-box ng-model="favoriteColors" value="color">
更改为<check-box ng-model="favoriteColors.value" value="color">
。
您可以在plunkr中看到,当您点击复选框时,console.log
语句现在在$watch
函数下发生。
答案 2 :(得分:0)
我看到你正在使用angular-form-ui's checkbox directive。
$watchCollection
(link to documentation)而不是$watch
来观看数组的更改$scope.favoriteColors
初始化为包含应检查的值的数组我已将您的更改还原为angular-form-ui.js
,因为这些更改违反了指令。它们现在与latest commit on Github (checkbox.js)中显示的代码完全相同。只有一件事发生了变化,angular-form-ui
模块的初始化是通过将[]
作为第一行的第二个参数添加的。
以下是更新的plunker:http://plnkr.co/edit/mlUt46?p=preview