ngModel. $ modelValue และ ngModel แตกต่างกันอย่างไร $ viewValue


94

ฉันมีคำสั่ง ckEditor ต่อไปนี้ ด้านล่างมีสองรูปแบบที่ฉันได้เห็นจากตัวอย่างวิธีการตั้งค่าข้อมูลในตัวแก้ไข:

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);
            };
        }
    };
}])

ใครช่วยบอกหน่อยได้ไหมว่าอะไรคือความแตกต่างระหว่าง:

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

และควรใช้ตัวไหน ฉันดูเอกสารเชิงมุมแล้วมันบอกว่า:

$viewValue

Actual string value in the view.

$modelValue

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

ฉันไม่รู้ว่าผู้เขียนหมายถึงอะไรเมื่อเขาเขียนสิ่งนี้ในเอกสาร :-(

คำตอบ:


151

คุณกำลังดูเอกสารที่ถูกต้อง แต่คุณอาจสับสนเล็กน้อย $modelValueและ$viewValueมีความแตกต่างที่แตกต่างกัน นี่คือ:

ดังที่คุณได้ระบุไว้ข้างต้น:

$viewValue:ค่าสตริง(หรือวัตถุ) จริงในมุมมอง
$modelValue:ค่าในแบบจำลองที่ตัวควบคุมถูกผูกไว้

ฉันจะสมมติว่า ngModel ของคุณอ้างถึง<input />องค์ประกอบ ... ? ของคุณ<input>มีค่าสตริงที่แสดงต่อผู้ใช้ใช่ไหม? แต่โมเดลที่แท้จริงอาจเป็นเวอร์ชันอื่นของสตริงนั้น ตัวอย่างเช่นอินพุตอาจแสดงสตริง'200'แต่<input type="number">(ตัวอย่าง) จะมีค่าโมเดล200เป็นจำนวนเต็ม ดังนั้นการแสดงสตริงที่คุณ "มุมมอง" ใน<input>เป็นและตัวเลขแสดงจะเป็น ngModel.$viewValuengModel.$modelValue

อีกตัวอย่างหนึ่งคือ<input type="date">ตำแหน่งที่$viewValueจะเป็นสิ่งที่ต้องการJan 01, 2000และ$modelValueจะเป็นDateวัตถุจาวาสคริปต์จริงที่แสดงสตริงวันที่ มันสมเหตุสมผลไหม

ฉันหวังว่าจะตอบคำถามของคุณ


โดยพื้นฐานแล้ว$viewValueเป็นสตริงเสมอหรือไม่?
cdmckay

7
ตามที่เอกสารกล่าว: $viewValue: Actual string value in the view.. ใช่.
เทนนิส

7
หมายเหตุอื่น เมื่อมี<input type="text">ค่าเป็นที่ว่างเปล่าที่$modelValueทรัพย์สินundefinedในขณะที่$viewValueเป็น''สตริงที่ว่างเปล่า สิ่งนี้สามารถสร้างความแตกต่างได้หากคุณกำลังดม "ความยาว" $modelValueซึ่งใช้ไม่ได้ผล แต่$viewValueจะ
BradGreens

8
$viewValueไม่เสมอสตริง เป็นสตริงสำหรับคำสั่ง Angular core ปัจจุบัน แต่อาจเป็นแบบดั้งเดิมหรือ Object ในคอนโทรลแบบกำหนดเองของคุณ ตัวอย่างที่ดีคือ<input file="type">คอมโพเนนต์โดยที่ viewValue มีFileListอ็อบเจ็กต์ที่มีไฟล์แนบโดยผู้ใช้ เอกสารเชิงมุมสับสนเกี่ยวกับเรื่องนี้ในขณะนี้และควรได้รับการอัปเดต
demisx

4
นอกจากนี้หากอินพุตไม่ถูกต้องจะไม่มีการตั้งค่า $ modelValue กล่าวคือถ้าคุณมี <input ng-minlength = "8" ... > และคุณอินพุตมีความยาวเพียง 5 อักขระ $ viewValue จะแสดงอักขระ 5 ตัวนั้น แต่จะไม่มี $ modelValue
honkskillet

27

คุณสามารถเห็นสิ่งต่างๆดังนี้:

  • $modelValue คือ API ภายนอกของคุณกล่าวคือมีบางอย่างที่เปิดเผยกับคอนโทรลเลอร์ของคุณ
  • $viewValue เป็น API ภายในของคุณคุณควรใช้ภายในเท่านั้น

เมื่อแก้ไข$viewValueจะไม่มีการเรียกวิธีการแสดงผลเนื่องจากเป็น "รูปแบบการแสดงผล" คุณจะต้องดำเนินการด้วยตนเองในขณะที่วิธีการแสดงผลจะถูกเรียกโดยอัตโนมัติเมื่อมี$modelValueการปรับเปลี่ยน

อย่างไรก็ตามข้อมูลจะยังคงสอดคล้องกันขอบคุณ$formattersและ$parsers:

  • ถ้าคุณเปลี่ยน$viewValue, จะแปลมันกลับไป$parsers $modelValue
  • ถ้าคุณเปลี่ยน$modelValue, จะแปลงเป็น$formatters$viewValue

เมื่อแก้ไข $ viewValue เมธอดการแสดงผลจะไม่ถูกเรียกหากคุณเปลี่ยน $ viewValue $ parsers จะแปลกลับเป็น $ modelValue หมายความว่า $ modelvalue change และวิธีการแสดงผลจะถูกเรียกโดยอัตโนมัติเมื่อทำการปรับเปลี่ยน $ modelValue โดยทางอ้อม เมื่อ $ viewValue เปลี่ยนไปจะเรียกวิธีการแสดงผล ใช่ไหม ?
Mukund Kumar

1
คุณต้องเจาะลึกเข้าไปในไปป์ไลน์การผูกแบบสองทาง Angular ngModel เพื่อทำความเข้าใจว่ามันทำงานอย่างไร เมื่อการปรับปรุง $viewValueผ่านทางsetViewValue(viewValue)วิธีการ parsers / validators เตะใน (ถ้ามี) และแจงว่าviewValueไป modelValue viewChangeListenersตรวจสอบมันเขียนไปยังขอบเขตแล้วเตะของ ครั้งต่อไปที่ย่อยวิ่งค่ารูปแบบจะถูกดึงจากขอบเขตและเมื่อเทียบกับ $ modelValue ในการควบคุม: github.com/angular/angular.js/blob/master/src/ng/directive/... หากเท่ากัน (และจะเท่ากันในสถานการณ์ของคุณ) ก็จะส่งกลับ
demisx

18

Angular ต้องติดตามข้อมูล ngModel สองมุมมอง - มีข้อมูลตามที่ DOM (เบราว์เซอร์) เห็นจากนั้นจะมีการประมวลผลการแสดงค่าเหล่านั้นของ Angular $viewValueคุ้มค่าด้าน DOM ตัวอย่างเช่นใน<input>ส่วน$viewValueนี้คือสิ่งที่ผู้ใช้พิมพ์ลงในเบราว์เซอร์ของตน

เมื่อสิ่งที่คนในประเภท<input>นั้น$viewValueจะถูกประมวลผลโดย $ parsers $modelValueและกลายเป็นมุมมองของค่าเชิงมุมของที่เรียกว่า

ดังนั้นคุณสามารถคิดว่า$modelValueเป็นค่าเวอร์ชันประมวลผลของเชิงมุมซึ่งเป็นค่าที่คุณเห็นในแบบจำลองในขณะที่$viewValueเป็นเวอร์ชันดิบ

$modelValueจะใช้เวลานี้หนึ่งก้าวจินตนาการที่เราทำบางสิ่งบางอย่างที่มีการเปลี่ยนแปลง Angular เห็นการเปลี่ยนแปลงนี้และเรียกใช้ $ formatters เพื่อสร้างการปรับปรุง$viewValue(ตาม $ modelValue ใหม่) เพื่อส่งไปยัง DOM


คุณหมายถึง $ modelValue หรือ $ modelView ?? หาก $ modelValue โปรดแก้ไขการพิมพ์ผิด
แพลงก์ตอน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.