0

我不清楚scope.ngModelcontroller.$viewValue/controller.$modelValue/controller.$setViewValue()之間的關係是什麼,具體而言,後三者的觀點是什麼。例如,參見this jsfiddle

<input type="text" ng-model="foo" my-directive> 

和:

myApp.directive('myDirective', function($timeout) { 
    return { 
     require: 'ngModel', 
     restrict: 'A', 
     scope: { ngModel: '=' }, 
     link: function (scope, element, attrs, controller) { 
      function log() { 
       console.log(scope.ngModel); 
       console.log(controller.$viewValue); 
       console.log(controller.$modelValue); 
      } 
      log(); 
      controller.$setViewValue("boorb"); 
      log(); 
      scope.$watch('ngModel', function (val) { 
       console.log("val is now", val); 
      }); 

      $timeout(function() { 
       log(); 
      }, 2000); 

     } 
    } 
}); 

隨着所述控制器:

function MyCtrl($scope, $timeout) { 
    $scope.foo = 'ahha'; 
    $timeout(function() { 
     $scope.foo = "good"; 
    }, 1000); 
} 

的輸出是:

(index):45 ahha 
(index):46 NaN 
(index):47 NaN 
(index):45 ahha 
(index):46 boorb 
(index):47 boorb 
(index):53 val is now ahha 
(index):53 val is now good 
(index):45 good 
(index):46 boorb 
(index):47 boorb 

controller.$viewValue做不是S作爲foo變量的值出發。此外,controller.$setViewValue("boorb")完全不影響scope.ngModel,更新也不反映在HTML中。因此,似乎scope.ngModelcontroller.$viewValue之間沒有關係。看來,我想要做的任何事情,我只會使用scope.ngModel,並觀看這些值。什麼是使用controller.$viewValuecontroller.$modelValue或保持與scope.ngModel最新?

+0

有幫助的:http://radify.io/blog/understanding-ngmodelcontroller-by-example-part-1/ – Claudiu

回答

0

這裏的困惑來自堅持現有指令的指令,即ngInput

相反,考慮一個新的指令:

<my-directive ng-model="ugh">Sup</my-directive> 

有了:

$rootScope.ugh = 40; 

和:

.directive('myDirective', function() { 
    return { 
    require: "ngModel", 

    // element-only directive 
    restrict: "E", 

    // template turns the directive into one input tag 
    // 'inner' is on the scope of the *directive* 
    template: "<input type='text' ng-model='inner'/>",  

    // the directive will have its own isolated scope 
    scope: { }, 

    link: function (scope, element, attrs, ngModelCtrl) { 
     // formatter goes from modelValue (i.e. $rootScope.ugh) to 
     // view value (in this case, the string of twice the model 
     // value + '-' 
     ngModelCtrl.$formatters.push(function (modelValue) { 
     return ('' + (modelValue * 2)) + '-'; 
     }); 

     // render does what is necessary to display the view value 
     // in this case, sets the scope.inner so that the inner 
     // <input> can render it 
     ngModelCtrl.$render = function() { 
     scope.inner = ngModelCtrl.$viewValue; 
     }; 

     // changes on the inner should trigger changes in the view value 
     scope.$watch('inner', function (newValue) { 
     ngModelCtrl.$setViewValue(newValue); 
     }); 

     // when the view value changes, it gets parsed back into a model 
     // value via the parsers, which then sets the $modelValue, which 
     // then sets the underlying model ($rootScope.ugh) 
     ngModelCtrl.$parsers.push(function (viewValue) { 
     var sub = viewValue.substr(0, viewValue.length-1); 
     return parseInt(sub)/2; 
     }); 
    } 
    }; 
}) 

試試它Plunker

請注意,typeof ugh保持"number",即使指令的視圖值是不同的類型。

0

scope: { ngModel: '=' },爲該指令創建一個隔離範圍,這意味着該指令中foo的更改將不再反映在MyCtrl的父範圍中。

此外,$setViewValue()所做的更改不會反映到DOM中,直到controller.$render()被調用,它告訴Angular在下一個摘要循環中更新DOM。

但要回答這個問題,NgModelController及其方法真的只有在需要創建一些特殊的自定義數據綁定指令時纔是必需的。對於正常的數據輸入和驗證,您不需要使用它。從the documentation(重點是我的):

[NgModelController]包含數據綁定,驗證,CSS更新和值格式化和解析的服務。它有目的地不包含處理DOM渲染或監聽DOM事件的邏輯。這種DOM相關邏輯應該由其他指令提供,這些指令使用NgModelController來控制元素的數據綁定。 Angular爲大多數輸入元素提供了此DOM邏輯。