鍍金池/ 問答/HTML/ angularjs1.6 使用$setViewValue無法更新model數(shù)值

angularjs1.6 使用$setViewValue無法更新model數(shù)值

視圖代碼

<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函數(shù)可以改變ngModel值,并且通過管道函數(shù)$parsers,然而del函數(shù)使用了splice處理數(shù)組,卻無法通過管道函數(shù)并且實(shí)現(xiàn)更新model值。

我嘗試過使用$scope.$apply()在ngModel.$setViewValue($scope.images)后執(zhí)行,依然無法解決。

使用的angular版本為1.6.6。

在線運(yùn)行代碼,在線代碼鏈接,希望大家?guī)臀铱聪聠栴}到底出現(xiàn)在哪里?

回答
編輯回答
悶油瓶

$scope.images是引用變量,在set函數(shù)里重新給它賦值了,它指向的內(nèi)存地址變化了,所以傳進(jìn)$setViewValue后,$setViewValue檢測到這個(gè)變量變化了所以正常調(diào)用了$parsers函數(shù)數(shù)組等。但是在del函數(shù)里只是用splice刪除了其中一個(gè)元素,$scope.images指向的內(nèi)存地址沒有變化,所以$setViewValue沒有檢測到這個(gè)變量有變化也就不會(huì)調(diào)用$parsers函數(shù)數(shù)組了。
在del里splice前加一句:
$scope.images = $scope.images.slice();就行了,復(fù)制$scope.images并將$scope.images指向這個(gè)復(fù)制的內(nèi)存地址就好了,這樣就改變了$scope.images指向的內(nèi)存地址。

不過話說會(huì)來,為什么要搞得這么麻煩呢?應(yīng)該有更簡單的實(shí)現(xiàn)方法吧。

2017年2月10日 06:05