21

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

如果您查看 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

问题是model.$modelValueNaN的类型甚至不应该是数字。尽管如此,降价呈现。我可以加一张typeof model.$modelValue == 'string'支票,但我宁愿处理根本原因。任何的想法?

4

4 回答 4

30

我不知道 $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();
            }

            //...
        }
    };
});

$watch 返回一个注销函数,因此一旦为 $modelValue 分配了新值,就可以注销它。

于 2014-08-22T13:42:04.300 回答
19

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

像这样:

.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;
                   }

               }}
       })
于 2015-03-26T10:54:55.940 回答
13

您的指令中的问题是,在评估表达式之前,角度会触发一次手表。所以第一次的价值是undefined。我不相信这是可以避免的,但 AngularJS 是如何工作的。

val在你的渲染函数中添加了一个参数来显示实际的观察值(记录到控制台——见底部的小提琴)。ngModelController 初始化$modelValue为 NaN ,这就是为什么NaN传递给函数而不是undefined.

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

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

更新了小提琴

于 2013-05-05T11:43:52.483 回答
4

另一个变体(如果有人会在这里找到这个问题):只需将指令的执行包装在 $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);
                           }
                       });
                   }}
           })
于 2013-07-31T22:27:10.663 回答