[AngularJS] ngModelController render function
ModelValue and ViewValue:
$viewValue: Actual string value in the view.
$modelValue: The value in the model that the control is bound to.
In Anuglar, it watchs the $modelValue for you and update $viewValue.
As you need to tell Angular when you set $viewValue and apply render() function to update.
Before the $render() function is called, the value will be passed into the $formatters.
$formatters: Array of functions to execute, as a pipeline, whenever the model value changes. The functions are called in reverse array order, each passing the value through to the next.
function formatter(value) { if (value) { return value.toUpperCase(); } } ngModel.$formatters.push(formatter);
Example:
/** * Created by Answer1215 on 12/18/2014. */ angular.module('app', []) .directive('bank', function($filter) { return{ restrict: 'E', template: '<div>Click me to add $10 into your account</div>', require: 'ngModel', //The ^ prefix means that this directive searches for the controller on its parents (without the ^ prefix, the directive would look for the controller on just its own element) link: function(scope, element, attrs, ngModelCtrl) { /* ngModelCtrl.$formatters.push(function(modelValue) { return "$" + modelValue; });*/ //formatter is called before the render ngModelCtrl.$formatters.push($filter('currency')); //$render function require user to implement it ngModelCtrl.$render = function() { element.text('Now you have: ' + ngModelCtrl.$viewValue); } } } })
<!DOCTYPE html> <html ng-app="app"> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <div ng-init="money=10"></div> <bank ng-model="money"></bank><br/> <input type="text" ng-model="money" /><button type="reset" ng-click="money=0">Reset</button> <script src="bower_components/angular/angular.min.js"></script> <script src="app.js"></script> </body> </html>
$rollbackViewValue(): Cancel an update and reset the input element's value to prevent an update to the $modelValue
, which may be caused by a pending debounced event or because the input is waiting for a some future event.
If you have an input that uses ng-model-options
to set up debounced events or events such as blur you can have a situation where there is a period when the $viewValue
is out of synch with the ngModel's $modelValue
.
In this case, you can run into difficulties if you try to update the ngModel's $modelValue
programmatically before these debounced/future events have resolved/occurred, because Angular's dirty checking mechanism is not able to tell whether the model has actually changed or not.
The $rollbackViewValue()
method should be called before programmatically changing the model of an input which may have such events pending. This is important in order to make sure that the input field will be updated with the new model value and any pending operations are cancelled.
See: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
$sec service: We are using the $sce service here and include the $sanitize module to automatically remove "bad" content like inline event listener (e.g.<span onclick="...">
). However, as we are using $sce
the model can still decide to provide unsafe content if it marks that content using the $sce
service.
angular.module('customControl', ['ngSanitize']). directive('contenteditable', ['$sce', function($sce) { return { restrict: 'A', // only activate on element attribute require: '?ngModel', // get a hold of NgModelController link: function(scope, element, attrs, ngModel) { if (!ngModel) return; // do nothing if no ng-model // Specify how UI should be updated ngModel.$render = function() { element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); }; // Listen for change events to enable binding element.on('blur keyup change', function() { scope.$evalAsync(read); }); read(); // initialize // Write data to the model function read() { var html = element.html(); // When we clear the content editable the browser leaves a <br> behind // If strip-br attribute is provided then we strip this out if ( attrs.stripBr && html == '<br>' ) { html = ''; } ngModel.$setViewValue(html); } } }; }]);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具