视图代码
<div ng-controller="appController">
<div image-uploads ng-model="files"></div>
<p style="display: block; color: red">{{files}}</p>
</div>
JS代码
var app = angular.module('app', []);
app.controller('appController', function ($scope) {
$scope.files = '1,2,3,4';
});
app.directive('imageUploads', function () {
return {
require: '?^ngModel',
restrict: 'EA',
template: '<div class="image-upload-box"><p class="image_upload" ng-repeat="image in images track by $index"><button ng-click="set()">setModel</button><button ng-click="del($index)">{{image}}</button></p></div>',
link: function ($scope, element, attrs, ngModel) {
ngModel.$formatters.push(function (modelValue) {
var images = new Array();
if (!ngModel.$isEmpty(modelValue)) {
var values = modelValue.split(",");
for (var j = 0; j < values.length; j++) {
images.push({
'id': values[j]
});
}
}
return images;
});
ngModel.$parsers.push(function (viewValue) {
var s = "";
for (var j = 0; j < viewValue.length; j++) {
if (viewValue[j].id != null) {
if (j > 0) {
s += ",";
}
s += viewValue[j].id;
}
}
return s;
});
ngModel.$render = function () {
$scope.images = ngModel.$viewValue;
};
$scope.del = function (i) {
$scope.images.splice(i, 1);
ngModel.$setViewValue($scope.images);
};
$scope.set = function () {
console.log('set');
$scope.images = [{id: 5}, {id: 6}, {id: 7}];
ngModel.$setViewValue($scope.images);
}
}
};
});
无法更新Model
使用set函数可以改变ngModel值,并且通过管道函数$parsers,然而del函数使用了splice处理数组,却无法通过管道函数并且实现更新model值。
我尝试过使用$scope.$apply()在ngModel.$setViewValue($scope.images)后执行,依然无法解决。
使用的angular版本为1.6.6。
在线运行代码,在线代码链接,希望大家帮我看下问题到底出现在哪里?
$scope.images是引用变量,在set函数里重新给它赋值了,它指向的内存地址变化了,所以传进$setViewValue后,$setViewValue检测到这个变量变化了所以正常调用了$parsers函数数组等。但是在del函数里只是用splice删除了其中一个元素,$scope.images指向的内存地址没有变化,所以$setViewValue没有检测到这个变量有变化也就不会调用$parsers函数数组了。
在del里splice前加一句:
$scope.images = $scope.images.slice();就行了,复制$scope.images并将$scope.images指向这个复制的内存地址就好了,这样就改变了$scope.images指向的内存地址。
不过话说会来,为什么要搞得这么麻烦呢?应该有更简单的实现方法吧。