2013-05-05 21 views
13

Xem jsfiddle này: http://jsfiddle.net/8bENp/66/

Nếu bạn nhìn vào bảng điều khiển JavaScript, bạn sẽ thấy một cái gì đó như thế này:

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 

Vấn đề là model.$modelValueNaN khi loại của nó không phải là số. Tuy nhiên, markdown ám. Tôi có thể thêm một kiểm tra typeof model.$modelValue == 'string', nhưng tôi muốn điều trị nguyên nhân cơ bản. Bất kỳ ý tưởng?

Trả lời

9

Vấn đề trong chỉ thị của bạn là góc kích hoạt đồng hồ một lần trước khi biểu thức được đánh giá. Vì vậy, lần đầu tiên giá trị là undefined. Tôi không tin rằng có thể được ngăn chặn, nhưng là cách AngularJS hoạt động.

Tôi đã thêm tham số val vào hàm hiển thị của bạn để hiển thị giá trị được xem thực tế (đã đăng nhập vào bảng điều khiển - xem phần đuôi ở dưới cùng). ngModelControllerinitializes $modelValue to NaN, đó là lý do tại sao NaN được chuyển đến hàm thay vì undefined.

Nhưng vì dường như chức năng makeHtml mong đợi một chuỗi, một sửa chữa dễ dàng là chuyển nó thành một chuỗi rỗng nếu giá trị là sai (có thể tốt hơn để chuyển đổi nó thành chuỗi).

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

Updated fiddle.

+0

Cảm ơn Martin. Tốt để biết điều này. –

+0

Cảm ơn bạn rất nhiều. Và phải nói rằng đó là hành vi rất trực quan, tôi đã dành một giờ trong giao diện điều khiển nơi tôi thấy giá trị nhưng mã của tôi - không. –

4

Một biến thể khác (chỉ khi ai đó sẽ tìm thấy câu hỏi đó ở đây): chỉ cần thực hiện quấn chỉ thị trong hàm $ timeout. Ví dụ: chỉ thị của tôi sử dụng nó:

.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

Điều này đã khắc phục được sự cố của tôi :) –

+12

Điều đó thật bẩn. – CQQL

+0

Vì ngModel được tạo thành một phần, các lỗi có thể xảy ra trừ khi kiểm tra được thực hiện, chẳng hạn như: 'if (! NgModel) {return;}'. –

24

Tôi không biết rằng $ modelValue được khởi tạo thành NaN và gặp phải vấn đề tương tự. Nếu $ modelValue là thực sự cần thiết lúc khởi tạo, một giải pháp có thể để xem nó cho đến khi nó đã được gán một giá trị mới:

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

      //... 
     } 
    }; 
}); 

Các $ đồng hồ trả về một chức năng xoá đăng ký, vì vậy nó có thể được đăng ký càng sớm càng một giá trị mới đã được gán cho $ modelValue.

+0

Tôi không hiểu làm thế nào mà làm việc, nhưng nó đã làm việc.:) –

+0

Công việc rất hữu ích và chính xác với ngModelController – BILL

+0

Khi giá trị trả về của hàm đầu tiên thay đổi, hàm thứ hai sẽ chạy. 'NaN' không bao giờ bằng' NaN' (tại sao nó là mặc định), vì vậy 'initialize' luôn chạy sau khi thay đổi mô hình đầu tiên. –

13

Tôi nghĩ bạn cũng có thể quấn nó trong một hàm ngModel.$render.

Giống như vậy:

.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

Bỏ phiếu cho câu trả lời này. Đối với những người muốn tương tác với mô hình, bạn có thể có giá trị mô hình thực tế mà không có lỗi. –

+0

nó cũng cố định vấn đề của tôi !! –

Các vấn đề liên quan