How to access $modelValue and $viewValue from insi

2019-07-29 02:08发布

问题:

While trying to access $modelValue and $viewValue from inside custom directives, I am getting null.

var demo = angular.module('demo', []);
demo.directive('dogInfo', function($parse) {
    return {
        restrict: 'E',
        require: 'ngModel',
        template: "<div> Dog's name: {{dogname}}<br>View Name: {{viewValue}}<br>Model Value: {{modelValue}}<br> Tag name: {{tagName}}</div>",
        link: function (scope, element, attrs, controller) {
            scope.viewValue = controller.$viewValue;
            scope.modelValue = controller.$modelValue;
            scope.tagName = controller.$name;
        }
    }});

function MyCtrl ($scope) {
    $scope.dogname = 'Hero';  // now    
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<div ng-app='demo'>
    <p ng-controller='MyCtrl'>
       <dog-info ng-model="dogname" name="Doggggyyy"/>.
    </p>
</div>

I am getting this output :

Dog's name: Hero
View Name: null
Model Value: null
Tag name: Doggggyyy

Here's the fiddle : http://jsfiddle.net/cxdun3y8/3/

回答1:

Try this approach:

demo.directive('dogInfo', function($parse) {
    return {
        restrict: 'E',
        require: 'ngModel',
        template: "<div> Dog's name: {{dogname}}<br>View Name: {{model.$viewValue}}<br>Model Value: {{modelValue}}<br> Tag name: {{tagName}}</div>",
        link: function (scope, element, attrs, controller) {
            scope.model = controller;
            scope.viewValue = controller.$viewValue;
            scope.modelValue = controller.$modelValue;
            scope.tagName = controller.$name;
        }
    }});

Pay attention to how I pass data to the view



回答2:

According to answers here there are three working solutions

1) Using $timeout to wait until first digest end

$timeout(function() {
  initialViewValue = controller.$viewValue;
}, 0)

2) Using scope.watch

const off = scope.$watch(attrs.ngModel, () => {
  initialViewValue = controller.$viewValue;
  off();
});

3) Using $parse to get value immediately

const getter = $parse(attrs.ngModel);
let initialViewValue = getter(scope);

Also viewValue available as argument inside formatter callback

controller.$formatters.push(function(value) {
   viewValue = value
});

You'll probably want to remove callback if you only want to get initial value