Sự khác biệt giữa ngModel. $ ModelValue và ngModel. $ ViewValue


94

Tôi có lệnh ckEditor sau đây. Ở dưới cùng là hai biến thể mà tôi đã thấy từ các ví dụ về cách đặt dữ liệu trong trình chỉnh sửa:

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

Ai đó có thể cho tôi biết sự khác biệt giữa:

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

Và tôi nên sử dụng cái nào. Tôi đã xem tài liệu góc cạnh và nó nói:

$viewValue

Actual string value in the view.

$modelValue

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

Tôi không hiểu tác giả muốn nói gì khi viết điều này trong tài liệu :-(

Câu trả lời:


151

Bạn đang xem tài liệu chính xác, nhưng có thể bạn hơi bối rối. các $modelValue$viewValue có một sự khác biệt rõ rệt. Nó là đây:

Như bạn đã lưu ý ở trên:

$viewValue:Giá trị chuỗi (hoặc Đối tượng) thực tế trong dạng xem.
$modelValue:Giá trị trong mô hình mà điều khiển bị ràng buộc.

Tôi sẽ giả định rằng ngModel của bạn đang đề cập đến một <input />phần tử ...? Vì vậy, của bạn <input>có một giá trị chuỗi mà nó hiển thị cho người dùng, phải không? Nhưng mô hình thực tế có thể là một số phiên bản khác của chuỗi đó. Ví dụ: đầu vào có thể hiển thị chuỗi '200'nhưng <input type="number">(ví dụ) sẽ thực sự chứa giá trị mô hình 200dưới dạng số nguyên. Vì vậy, biểu diễn chuỗi mà bạn "xem" trong <input>ngModel.$viewValuevà biểu diễn số sẽ là ngModel.$modelValue.

Một ví dụ khác sẽ là <input type="date">nơi mà $viewValuesẽ là một cái gì đó giống như thế Jan 01, 2000$modelValuesẽ là một Dateđối tượng javascript thực tế đại diện cho chuỗi ngày đó. Điều đó có ý nghĩa?

Tôi hy vọng trả lời câu hỏi của bạn.


Vì vậy, về cơ bản, $viewValueluôn luôn là một chuỗi?
cdmckay

7
Như các tài liệu nói: $viewValue: Actual string value in the view.. Vì vậy, có.
tennisgent

7
Một lưu ý khác. Khi một <input type="text">giá trị là trống rỗng, các $modelValuetài sản là undefined, trong khi đó $viewValue''chuỗi rỗng. Điều này có thể tạo ra sự khác biệt nếu bạn đánh hơi thấy "độ dài" của $modelValuenó sẽ không hoạt động, nhưng $viewValuesẽ.
BradGreens

8
Các $viewValuekhông phải lúc nào cũng là một chuỗi. Nó là một chuỗi cho các chỉ thị lõi Angular hiện tại, nhưng nó có thể là một nguyên thủy hoặc một Đối tượng trong các điều khiển tùy chỉnh của bạn. Một ví dụ điển hình là <input file="type">thành phần, nơi viewValue chứa FileListđối tượng với các tệp được đính kèm bởi người dùng. Các tài liệu Angular hiện đang khó hiểu về điều này và cần được cập nhật.
demisx

4
Cũng không nếu đầu vào không hợp lệ, $ modelValue sẽ không được đặt. Tức là, nếu bạn có <input ng-minlength = "8" ...> và bạn nhập chỉ có 5 ký tự, $ viewValue sẽ hiển thị 5 ký tự đó nhưng $ modelValue sẽ không tồn tại.
honkskillet

27

Bạn có thể thấy những thứ như sau:

  • $modelValue là API bên ngoài của bạn, có nghĩa là, một cái gì đó được tiếp xúc với bộ điều khiển của bạn.
  • $viewValue là API nội bộ của bạn, bạn chỉ nên sử dụng nó trong nội bộ.

Khi chỉnh sửa $viewValue, phương thức kết xuất sẽ không được gọi, vì nó là "mô hình kết xuất". Bạn sẽ phải làm điều đó theo cách thủ công, trong khi phương thức kết xuất sẽ được gọi tự động khi $modelValuesửa đổi.

Tuy nhiên, thông tin sẽ vẫn nhất quán, nhờ $formatters$parsers:

  • Nếu bạn thay đổi $viewValue, $parserssẽ dịch nó trở lại $modelValue.
  • Nếu bạn thay đổi $modelValue, $formatterssẽ chuyển đổi nó thành $viewValue.

Khi chỉnh sửa $ viewValue, phương thức kết xuất sẽ không được gọi. Nếu bạn thay đổi $ viewValue, $ parsers sẽ dịch nó trở lại thành $ modelValue.means $ modelvalue change. Và phương thức kết xuất sẽ được gọi tự động khi sửa đổi $ modelValue. Ngoài ra gián tiếp, khi $ viewValue thay đổi, phương thức kết xuất được gọi. Là nó ?
Mukund Kumar,

1
Bạn cần tìm hiểu kỹ về đường dẫn liên kết hai chiều Angular ngModel để hiểu cách hoạt động của nó. Khi cập nhật $viewValuethông qua setViewValue(viewValue)phương thức, trình phân tích cú pháp / trình xác thực bắt đầu (nếu có) và phân tích cú pháp đó viewValuethành modelValue, xác thực nó, ghi nó vào phạm vi và sau đó bắt đầu viewChangeListeners. Lần tiếp theo thông báo chạy, giá trị mô hình được truy xuất từ ​​phạm vi và so sánh với $ modelValue trong bộ điều khiển: github.com/angular/angular.js/blob/master/src/ng/directive/… . Nếu chúng bằng nhau (và chúng sẽ bằng nhau trong kịch bản của bạn), thì nó sẽ trả về.
demisx

18

Angular phải theo dõi hai chế độ xem của dữ liệu ngModel - đó là dữ liệu được nhìn thấy bởi DOM (trình duyệt) và sau đó có phần biểu diễn được xử lý của Angular về các giá trị đó. Là $viewValuegiá trị bên DOM. Vì vậy, ví dụ, trong một <input>sự $viewValuelà những gì người dùng gõ vào trình duyệt của họ.

Khi ai đó nhập nội dung nào đó vào <input>thì $viewValue$ parsers sẽ xử lý và chuyển thành dạng xem của Angular về giá trị được gọi $modelValue.

Vì vậy, bạn có thể $modelValuecoi đây là phiên bản đã xử lý của giá trị theo góc cạnh, giá trị bạn thấy trong mô hình, trong khi đó $viewValuelà phiên bản thô.

Để thực hiện thêm một bước này, hãy tưởng tượng chúng tôi làm điều gì đó thay đổi $modelValue. Angular nhận thấy sự thay đổi này và gọi $ formatters để tạo một bản cập nhật $viewValue(dựa trên $ modelValue mới) để gửi đến DOM.


ý bạn là $ modelValue hay $ modelView ?? Nếu $ modelValue, vui lòng sửa lỗi chính tả.
Plankton,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.