Quelle est la différence entre ngModel. $ ModelValue et ngModel. $ ViewValue

94

J'ai la directive ckEditor suivante. En bas se trouvent deux variantes que j'ai vues à partir d'exemples sur la façon de définir les données dans l'éditeur:

app.directive('ckEditor', [function () {
    return {
        require: '?ngModel',
        link: function ($scope, elm, attr, ngModel) {

            var ck = null;
            var config = attr.editorSize;
            if (config == 'wide') {
                ck = CKEDITOR.replace(elm[0], { customConfig: 'config-wide.js' });
            } else {
                ck = CKEDITOR.replace(elm[0], { customConfig: 'config-narrow.js' });
            }


            function updateModel() {
                $scope.$apply(function () {
                    ngModel.$setViewValue(ck.getData());
                });
            }

            $scope.$on('modalObjectSet', function (e, modalData) {
                // force a call to render
                ngModel.$render();
            });

            ck.on('change', updateModel);
            ck.on('mode', updateModel);
            ck.on('key', updateModel);
            ck.on('dataReady', updateModel);

            ck.on('instanceReady', function () {
                ngModel.$render();
            });

            ck.on('insertElement', function () {
                setTimeout(function () {
                    $scope.$apply(function () {
                        ngModel.$setViewValue(ck.getData());
                    });
                }, 1000);
            });

            ngModel.$render = function (value) {
                ck.setData(ngModel.$modelValue);
            };

            ngModel.$render = function (value) {
                ck.setData(ngModel.$viewValue);
            };
        }
    };
}])

Quelqu'un peut-il me dire quelle est la différence entre:

ck.setData(ngModel.$modelValue);
ck.setData(ngModel.$viewValue);

Et lequel dois-je utiliser. J'ai regardé la documentation angulaire et il est dit:

$viewValue

Actual string value in the view.

$modelValue

The value in the model, that the control is bound to.

Je n'ai aucune idée de ce que l'auteur voulait dire quand il a écrit ceci dans le document :-(

Samantha JT Star
la source

Réponses:

151

Vous regardez la documentation correcte, mais il se peut que vous soyez un peu confus. Les $modelValueet $viewValueont une différence distincte. C'est ça:

Comme vous l'avez déjà noté ci-dessus:

$viewValue:Valeur réelle de la chaîne (ou de l'objet) dans la vue.
$modelValue:Valeur du modèle à laquelle le contrôle est lié.

Je vais supposer que votre ngModel fait référence à un <input />élément ...? Donc, votre <input>a une valeur de chaîne qu'il affiche à l'utilisateur, non? Mais le modèle réel pourrait être une autre version de cette chaîne. Par exemple, l'entrée peut afficher la chaîne '200'mais le <input type="number">(par exemple) contiendra en fait une valeur de modèle 200sous la forme d'un entier. Ainsi, la représentation sous forme de chaîne que vous «visualisez» dans le <input>est le ngModel.$viewValueet la représentation numérique sera le ngModel.$modelValue.

Un autre exemple serait un <input type="date">où le $viewValueserait quelque chose comme Jan 01, 2000et le $modelValueserait un Dateobjet javascript réel qui représente cette chaîne de date. Cela a-t-il du sens?

J'espère que cela répond à votre question.

tennisgent
la source
Donc, fondamentalement, $viewValueest-ce toujours une chaîne?
cdmckay
7
Comme les docs disent: $viewValue: Actual string value in the view.. Donc oui.
tennisgent
7
Une autre note. Lorsqu'une <input type="text">valeur est vide, la $modelValuepropriété est undefined, tandis que la $viewValueest ''une chaîne vide. Cela peut faire une différence si vous reniflez la "longueur" de ce $modelValuequi ne fonctionnera pas, mais le $viewValuefera.
BradGreens
8
Le $viewValuen'est pas toujours une chaîne. Il s'agit d'une chaîne pour les directives de base angulaires actuelles, mais il peut s'agir d'une primitive ou d'un objet dans vos contrôles personnalisés. Un bon exemple est le <input file="type">composant, où viewValue contient un FileListobjet avec des fichiers attachés par l'utilisateur. Les documents Angular sont déroutants à ce sujet pour le moment et devraient être mis à jour.
demisx
4
De même pas si l'entrée n'est pas valide, la valeur $ modelValue ne sera pas définie. C'est-à-dire que si vous avez <input ng-minlength = "8" ...> et que votre entrée ne comporte que 5 caractères, $ viewValue affichera ces 5 caractères mais $ modelValue n'existera pas.
honkskillet
27

Vous pouvez voir des choses comme ceci:

  • $modelValue est votre API externe, c'est-à-dire quelque chose exposé à votre contrôleur.
  • $viewValue est votre API interne, vous ne devez l'utiliser qu'en interne.

Lors de l'édition $viewValue, la méthode de rendu ne sera pas appelée, car il s'agit du "modèle rendu". Vous devrez le faire manuellement, tandis que la méthode de rendu sera appelée automatiquement lors des $modelValuemodifications.

Cependant, les informations resteront cohérentes, grâce à $formatterset $parsers:

  • Si vous changez $viewValue, $parsersle traduira de nouveau en $modelValue.
  • Si vous changez $modelValue, $formattersle convertira en $viewValue.
Vianney Dupoy de Guitard
la source
Lors de l'édition de $ viewValue, la méthode de rendu ne sera pas appelée.Si vous changez $ viewValue, $ parsers le traduira à nouveau en $ modelValue.means $ modelvalue change.et la méthode de rendu sera appelée automatiquement lors des modifications de $ modelValue. lorsque $ viewValue change, la méthode de rendu est appelée. c'est ça?
Mukund Kumar
1
Vous devez creuser dans le pipeline de liaison bidirectionnelle Angular ngModel pour comprendre comment cela fonctionne. Lors de la mise à jour $viewValuevia la setViewValue(viewValue)méthode, les analyseurs / validateurs entrent en jeu (le cas échéant) et viewValueanalysent cela dans la valeur de modèle, le valident, l'écrivent dans la portée, puis le coupent viewChangeListeners. Lors de la prochaine exécution du résumé, la valeur du modèle est extraite de la portée et comparée à la valeur $ modelValue dans le contrôleur: github.com/angular/angular.js/blob/master/src/ng/directive/… . S'ils sont égaux (et ils seront égaux dans votre scénario), alors il revient.
demisx
18

Angular doit garder une trace de deux vues des données ngModel - il y a les données vues par le DOM (navigateur), puis il y a la représentation traitée par Angular de ces valeurs. Le $viewValueest la valeur côté DOM. Ainsi, par exemple, dans un <input>le $viewValueest ce que l'utilisateur a tapé dans son navigateur.

Une fois que quelqu'un tape quelque chose, <input>il $viewValueest traité par $ parsers et transformé en vue Angular de la valeur qui est appelée $modelValue.

Ainsi, vous pouvez penser à $modelValuela version traitée angulaire de la valeur, la valeur que vous voyez dans le modèle, alors que $viewValuec'est la version brute.

Pour aller plus loin, imaginez que nous faisons quelque chose qui change le $modelValue. Angular voit ce changement et appelle $ formateurs pour créer une mise à jour $viewValue(basée sur le nouveau $ modelValue) à envoyer au DOM.

KayakDave
la source
u signifie $ modelValue ou $ modelView ?? Si $ modelValue, veuillez corriger la faute de frappe.
Plankton