[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);
      }
    }
  };
}]);
时间: 2024-10-13 08:48:28

[AngularJS] ngModelController render function的相关文章

[Vue warn]: You may have an infinite update loop in a component render function

[Vue warn]: You may have an infinite update loop in a component render function 这个问题很奇怪,之前从来没有遇到过.如果是我自己主导的项目,倒也好办,慢慢 debug 就是:偏偏在公司的项目里遇到这个问题,而公司项目的体系结构很复杂,我还没完全掌握.更恼火的是,因为体系复杂,debug 也非常困难,再加上尚无测试框架,这个难搞啊…… 好死不死的,当时是下午3.4点钟,正好到了肚饿的时刻,结果又落入低血糖状态,真是屋漏

[Preact] Use State and Props in the Component Render Function

Preact offers, in addition to the regular component API from React, the ability to access both props & state as function parameters to the render method. This lesson will cover an example of how to utilize this convenience along with how destructurin

AngularJS – ngModelController详解

ngModelController方法 $render(); 当视图需要更新的时候会被调用.使用ng-model的指令应该自行实现这个方法. $isEmpty(value); 该方法用于判断输入值是否为空. 例如,使用ngModelController的指令需要判断其中是否有输入值的时候会使用该方法.该方法可用来判断值是否为undefined,'',null或者NaN. 你可以根据自己的需要重载该方法. $setValidity(validationErrorKey, isValid); 该方法

Failed to mount component: template or render function not defined.

vue-loader13.0有一个变更就是默认启用了esModule 把vue-loader降至13.0以下,就可以解决 原文地址:https://www.cnblogs.com/qq364735538/p/9097157.html

[Vue warn]: Failed to mount component: template or render function not defined.解决方案

命名视图 vue router 里有一个 模式叫做 命名视图 本来一个页面里面只能有一个路由视图 对应 一个组件,现在可以多个路由视图 对应 多个组件. 出错点 点击标签之后,<router-view></router-view>中并没有内容出现.反而控制台中报错了. 原因 就是在写这里的时候,原来都是component,现在是components,多了一个s. . 原文地址:https://www.cnblogs.com/jianxian/p/11063738.html

AngularJS指令进阶 -- ngModelController详解

大家都知道AngularJS中的指令是其尤为复杂的一个部分,但是这也是其比较好玩的地方.这篇文章我们就来说一说如何在我们自定义的指令中,利用ngModel的controller来做双向数据绑定,本文对大家学习AngularJS具有一定的参考借鉴价值,有需要的朋友们可以参考借鉴. 前言 在Angular应用中,ng-model指令时不可缺少的一个部分,它用来将视图绑定到数据,是双向绑定魔法中重要的一环.ngModelController则是ng-model指令中所定义的controller.这个c

创建angularjs可复用组件

AngularJS框架可以用Service和Directive降低开发复杂性.这个特性非常适合用于分离代码,创建可测试组件,然后将它们变成可重用组件. Directive是一组独立的JavaScript.HTML和CSS,它们封装了一个特定的行为,它将成为将来创建的Web组件的组成部分,我们可以在各种应用中重用这些组件.在创建之后,我们可以直接通过一个HTML标签.自定义属性或CSS类.甚至可以是HTML注释,来执行一个Directive. 这一篇教程将介绍如何创建一个‘自定义步长选择’ Dir

angular的 表单

一般来讲表单可能遇到的问题:1.如何数据绑定.2.验证表单.3.显示出错信息.4.整个form的验证.5.避免提交没有验证通过的表单.6.防止多系提交. input属性:nameng-modelng-requiredng-minlengthng-maxlengthng-patternng-change值变化时的回调 {{myForm.username.$error}} Form控制变量字段是否未更改formName.inputFieldName.$pristine字段是否更改formName.i

依赖内置ng-model指令的自定义指令

ng-model是AngularJS的原生指令,通过require: 'ngModel'可以更加深入地处理数据的双向数据绑定. ng-model里面的属性有: $parsers:保存了从viewValue到modelValue绑定过程中的处理函数. $formatters:保存了从modelValue到viewValue绑定过程中的处理函数. $setViewValue:当AngularJS外部发生某件事情的时候,需要调用这个函数才能让AngularJS知道应该更新modelValue了. $r