javascript model.$modelValue 在指令中是 NaN

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16383767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 04:25:54  来源:igfitidea点击:

model.$modelValue is NaN in directive

javascriptangularjsangularjs-directive

提问by Distortum

See this jsfiddle: http://jsfiddle.net/8bENp/66/

看到这个jsfiddle:http: //jsfiddle.net/8bENp/66/

If you look at the JavaScript console, you'll see something like this:

如果您查看 JavaScript 控制台,您会看到如下内容:

TypeError: Object NaN has no method 'replace'
    at makeHtml (https://raw.github.com/coreyti/showdown/master/compressed/showdown.js:62:705)
    at render (http://fiddle.jshell.net/_display/:50:42)
    at link (http://fiddle.jshell.net/_display/:54:13)
    at k (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js:42:321)
    at e (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js:38:198)
    at k (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js:42:261)
    at e (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js:38:198)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js:37:332
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js:15:440
    at Object.e.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js:85:416) <markdown ng-model="someCode" class="ng-pristine ng-valid"> angular.min.js:60

The problem is that model.$modelValueis NaNwhen its type shouldn't even be a number. Nevertheless, the markdown renders. I could add a typeof model.$modelValue == 'string'check, but I'd rather treat the underlying cause. Any idea?

问题是,model.$modelValueNaN当它的类型甚至不应该是一个数字。然而,降价呈现。我可以添加一个typeof model.$modelValue == 'string'检查,但我宁愿处理根本原因。任何的想法?

采纳答案by Martin

The problem in your directive is that angular triggers the watch once before the expression has been evaluated. So the very first time the value is undefined. I don't believe that can be prevented, but is how AngularJS works.

您指令中的问题是,在评估表达式之前,angular 会触发一次手表。所以第一次的价值是undefined. 我不相信这是可以防止的,但这就是 AngularJS 的工作原理。

I added a valparameter to your render function to show the actual watched value (logged to the console--see the fiddle at the bottom). The ngModelControllerinitializes $modelValueto NaN, that's why NaNis passed to the function instead of undefined.

val向您的渲染函数添加了一个参数以显示实际监视值(记录到控制台 - 请参阅底部的小提琴)。在ngModelController初始化$modelValue为NaN,这就是为什么NaN传递给函数代替undefined

But since it seems as if the makeHtmlfunction expects a string, an easy fix is to pass it an empty string if the value is falsy (might be even better to convert it to a string).

但由于该makeHtml函数似乎需要一个字符串,因此一个简单的解决方法是,如果该值是假的,则将一个空字符串传递给它(将其转换为字符串可能会更好)。

var htmlText = converter.makeHtml(model.$modelValue || '');

Updated fiddle.

更新了小提琴

回答by

I was not aware that $modelValue was initialized to NaN and ran into a similar issue. If the $modelValue is really needed at initialization, a solution may be to watch it until it has been assigned a new value:

我不知道 $modelValue 被初始化为 NaN 并遇到了类似的问题。如果在初始化时确实需要 $modelValue,一个解决方案可能是观察它,直到它被分配一个新值:

.directive('contentEditor', function(){
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function($scope, $element, $attrs, ngModel){

            var unregister = $scope.$watch(function(){
                return ngModel.$modelValue;
            }, initialize);

            function initialize(value){
                ngModel.$setViewValue(value);
                unregister();
            }

            //...
        }
    };
});

The $watch returns a deregistration function, so it can be unregistered as soon as a new value has been assigned to $modelValue.

$watch 返回一个注销函数,因此一旦将新值分配给 $modelValue 就可以将其注销。

回答by Wim Verhavert

I think you can also wrap it in a ngModel.$renderfunction.

我认为你也可以将它包装在一个ngModel.$render函数中。

Like so:

像这样:

.directive('classOnValue', function($timeout) {
           return {
               restrict: 'A',
               require: 'ngModel',
               link: function(scope, element, attrs, ngModel) {

                   ngModel.$render = function(){
                       //Do something with your model
                       var actualValue = ngModel.$modelValue;
                   }

               }}
       })

回答by OZ_

Another variant (just if somebody will find that question here): just wrap execution of directive in $timeout function. As example, my directive which use it:

另一个变体(如果有人会在这里找到这个问题):只需在 $timeout 函数中包装指令的执行。例如,我使用它的指令:

.directive('classOnValue', function($timeout) {
               return {
                   restrict: 'A',
                   require: 'ngModel',
                   link: function(scope, element, attrs, ngModel) {
                       $timeout(function() {
                           var value = (attrs.value || ngModel.$modelValue || ngModel.$viewValue );
                           if (value) {
                               element.addClass(attrs.classOnValue);
                           }
                       });
                   }}
           })