ngModel Formatters and Parsers


103

Tôi đã đăng cùng một câu hỏi dưới dạng khác nhau, nhưng không ai trả lời. Tôi không hiểu rõ về những gì Bộ định dạng và Bộ phân tích cú pháp làm trong js góc cạnh.

Theo định nghĩa, cả Bộ định dạng và Bộ phân tích cú pháp đều giống với tôi. Có lẽ tôi sai, vì tôi chưa quen với góc cạnh này.

Định dạng định dạng

Mảng các hàm để thực thi, như một đường ống, bất cứ khi nào giá trị mô hình thay đổi. Lần lượt mỗi hàm được gọi, chuyển giá trị cho hàm tiếp theo. Được sử dụng để định dạng / chuyển đổi các giá trị để hiển thị trong điều khiển và xác nhận.

Định nghĩa trình phân tích cú pháp

Mảng các hàm để thực thi, như một đường dẫn, bất cứ khi nào điều khiển đọc giá trị từ DOM. Lần lượt mỗi hàm được gọi, chuyển giá trị cho hàm tiếp theo. Được sử dụng để khử trùng / chuyển đổi giá trị cũng như xác thực. Để xác thực, trình phân tích cú pháp phải cập nhật trạng thái hợp lệ bằng cách sử dụng $ setValidity () và trả về không xác định cho các giá trị không hợp lệ.

Vui lòng giúp tôi hiểu cả hai tính năng bằng một ví dụ đơn giản. Một minh họa đơn giản của cả hai sẽ được đánh giá cao.


2
Bộ định dạng sửa đổi giá trị hiển thị của một mô hình, như hiển thị (123) 123-1234cho một số điện thoại. Bộ phân tích cú pháp đọc dữ liệu mỗi khi nó thay đổi và thường được sử dụng để đặt trạng thái $ hợp lệ của đầu vào. Tài liệu có các ví dụ về cả hai.
km6zla

Câu trả lời:


155

Chủ đề này đã được đề cập thực sự tốt trong một câu hỏi liên quan: Làm thế nào để thực hiện lọc hai chiều trong AngularJS?

Tóm lại:

  • Bộ định dạng thay đổi cách các giá trị mô hình sẽ xuất hiện trong dạng xem.
  • Bộ phân tích cú pháp thay đổi cách các giá trị chế độ xem sẽ được lưu trong mô hình.

Đây là một ví dụ đơn giản, dựa trên một ví dụ trong tài liệu api NgModelController :

  //format text going to user (model to view)
  ngModel.$formatters.push(function(value) {
    return value.toUpperCase();
  });

  //format text from the user (view to model)
  ngModel.$parsers.push(function(value) {
    return value.toLowerCase();
  });

Bạn có thể thấy nó hoạt động: http://plnkr.co/UQ5q5FxyBzIeEjRYYVGX?plnkr=legacy

<input type="button" value="set to 'misko'" ng-click="data.name='misko'"/>
<input type="button" value="set to 'MISKO'" ng-click="data.name='MISKO'"/>
<input changecase ng-model="data.name" />

Khi bạn nhập tên vào (xem mô hình), bạn sẽ thấy rằng mô hình luôn là chữ thường. Tuy nhiên, khi bạn nhấp vào một nút và thay đổi tên theo chương trình (mô hình để xem), trường đầu vào luôn là chữ hoa.


2
có cách nào để đặt thay đổi này làm loại người dùng không? Bạn nói "programatically", nhưng tôi đang cố gắng để có được $ viewValue phải được định dạng như người dùng nhập vào các đầu vào, ví dụ cho số thẻ tín dụng định dạng
iamyojimbo

3
@SavvasNicholas Nếu tôi không nhầm, bạn sẽ sử dụng ngModel.$setViewValue(transformedInput);để đặt nó và ngModel.$render();kết xuất nó từ hàm $ parsers.
Jacob Ensor

Trong trường hợp của tôi, những gì $formatterslàm, ngay lập tức được hoàn nguyên bởi $validators. ; (
Mikhail Batcer

1
FYI các tham chiếu plunkr không tồn tại nữa
Chris Brown

1
Tôi nhận thấy các định dạng chỉ hoạt động nếu bạn nhấn nút, không phải nếu bạn gõ tên vào lĩnh vực này
nuander

6

Một cách sử dụng khác cho trình định dạng và phân tích cú pháp là khi bạn muốn lưu trữ ngày tháng theo giờ UTC và hiển thị chúng theo giờ địa phương trên đầu vào, tôi đã tạo chỉ thị trình chọn ngày dưới đây và bộ lọc utcToLocal cho việc này.

(function () {
    'use strict';

    angular
        .module('app')
        .directive('datepicker', Directive);

    function Directive($filter) {
        return {
            require: 'ngModel',
            link: function (scope, element, attr, ngModel) {
                element.addClass('datepicker');
                element.pickadate({ format: 'dd/mm/yyyy', editable: true });

                // convert utc date to local for display
                ngModel.$formatters.push(function (utcDate) {
                    if (!utcDate)
                        return;

                    return $filter('utcToLocal')(utcDate, 'dd/MM/yyyy');
                });

                // convert local date to utc for storage
                ngModel.$parsers.push(function (localDate) {
                    if (!localDate)
                        return;

                    return moment(localDate, 'DD/MM/YYYY').utc().toISOString();
                });
            }
        };
    }
})();

Nó sử dụng bộ lọc utcToLocal này để đảm bảo ngày nhập ở định dạng chính xác trước khi chuyển đổi sang giờ địa phương.

(function () {
    'use strict';

    angular
        .module('app')
        .filter('utcToLocal', Filter);

    function Filter($filter) {
        return function (utcDateString, format) {
            if (!utcDateString) {
                return;
            }

            // append 'Z' to the date string to indicate UTC time if the timezone isn't already specified
            if (utcDateString.indexOf('Z') === -1 && utcDateString.indexOf('+') === -1) {
                utcDateString += 'Z';
            }

            return $filter('date')(utcDateString, format);
        };
    }
})();

moment.js được sử dụng để chuyển đổi ngày địa phương thành utc.

pickadate.js là plugin datepicker được sử dụng

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.