2013-05-05 67 views
13

看到這個的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'支票,但我寧願處理根本原因。任何想法?

回答

9

您的指令中的問題是,角度在評估表達式之前觸發一次表。所以第一次的值是undefined。我不相信這是可以預防的,但是AngularJS是如何工作的。

我在渲染函數中添加了一個val參數來顯示實際觀看的值(記錄到控制檯 - 請參閱底部的小提琴)。 ngModelControllerinitializes $modelValue to NaN,這就是爲什麼NaN傳遞給函數而不是undefined

但是,由於makeHtml函數看起來好像是一個字符串,所以一個簡單的解決方法就是在值爲假的情況下傳遞一個空字符串(可能會更好地將其轉換爲字符串)。

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

Updated fiddle

+0

感謝馬丁。很高興知道這一點。 – 2013-05-05 13:19:22

+0

非常感謝。不得不說,這是非常直觀的行爲,我花了一個小時在控制檯,我看到的價值,但我的代碼 - 不是。 – 2013-07-31 22:12:01

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); 
          } 
         }); 
        }} 
      }) 
+1

這解決了我的問題:) – 2013-11-13 22:09:50

+12

太髒了。 – CQQL 2014-01-09 19:31:52

+0

由於ngModel是兼容的,除非進行檢查,否則可能會發生錯誤,如:if(!ngModel){return;}'。 – 2014-08-22 13:02:05

24

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

      //... 
     } 
    }; 
}); 

的$手錶返回註銷功能,因此它能夠儘快被註銷的新值已分配給$ modelValue。

+0

我不明白這是如何做的,但它的工作。:) – 2015-10-05 07:18:28

+0

對ngModelController非常有幫助和正確的工作 – BILL 2016-04-08 14:56:07

+0

當第一個函數的返回值更改時,將運行第二個函數。 'NaN'永遠不等於'NaN'(爲什麼它是默認的),所以'initialize'總是在第一次模型更改後運行。 – 2017-05-23 17:51:13

13

我想你也可以用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; 
        } 

       }} 
     }) 
+0

投票答覆。對於那些想要與模型進行交互的人來說,可以沒有錯誤地獲得實際的模型值。 – 2016-03-03 13:33:07

+0

它解決了我的問題! – 2016-07-20 06:09:44