2012-10-19 27 views
42

ember-data.js: https://github.com/emberjs/data/tree/0396411e39df96c8506de3182c81414c1d0eb981Lỗi nên được xử lý như thế nào khi sử dụng REST dữ liệu của Ember.js?

Nói tóm lại, khi có một lỗi, tôi muốn hiển thị thông báo lỗi trong giao diện, và sau đó người dùng có thể 1) hủy bỏ, mà sẽ rollback giao dịch 2) sửa lỗi đầu vào và thực hiện thành công giao dịch, vượt qua các xác thực trên máy chủ.

Dưới đây là đoạn mã từ nguồn. Nó không bao gồm gọi lại lỗi.

updateRecord: function(store, type, record) { 
    var id = get(record, 'id'); 
    var root = this.rootForType(type); 

    var data = {}; 
    data[root] = this.toJSON(record); 

    this.ajax(this.buildURL(root, id), "PUT", { 
    data: data, 
    context: this, 
    success: function(json) { 
     this.didUpdateRecord(store, type, record, json); 
    } 
    }); 
}, 

Nhìn chung, luồng nhận lỗi từ máy chủ và cập nhật chế độ xem là gì? Có vẻ như một cuộc gọi lại lỗi sẽ đặt mô hình ở trạng thái isError và sau đó chế độ xem có thể hiển thị các thông báo thích hợp. Ngoài ra, các giao dịch nên ở lại bẩn. Bằng cách đó, giao dịch có thể sử dụng rollback.

Dường như việc sử dụng store.recordWasInvalid sẽ đi đúng hướng.

+4

Vẫn chưa có cơ chế hoàn chỉnh để xử lý lỗi, xem https://github.com/emberjs/data/pull/376/, có lẽ bạn sẽ tìm thấy những gì bạn muốn. –

+0

Có, việc thiếu xử lý lỗi là đáng ngạc nhiên, nhưng nó là tốt đẹp mà không có xử lý lỗi như trái ngược với một thực hiện ngây thơ mà sẽ thay đổi sau này. Tôi đã viết ứng dụng Ember gần đây của tôi để tránh lỗi máy chủ bằng cách thực hiện một số xác thực trên phía máy khách, trước khi thực hiện 'App.store.commit()'. – Mars

Trả lời

8

DS.RESTAdapter chỉ cần xử lý lỗi nhiều hơn một chút trong this commit nhưng chúng tôi vẫn chưa ở điểm chúng tôi có đề xuất tuyệt vời về xử lý lỗi.

Nếu bạn có tham vọng/đủ điên cuồng để đưa ứng dụng vào sản xuất ngay hôm nay với dữ liệu ember (như tôi đã làm!), Tốt nhất là đảm bảo rằng khả năng xảy ra lỗi trong API của bạn rất thấp. nghĩa là xác thực phía máy khách dữ liệu của bạn.

Hy vọng rằng, chúng tôi có thể cập nhật câu hỏi này với câu trả lời tốt hơn nhiều trong những tháng tới.

+0

Trạng thái xử lý lỗi trong Ember.Data hôm nay là gì? –

2

Vì hiện tại không có giải pháp tốt trong kho dữ liệu Ember-Data, tôi đã thực hiện giải pháp của riêng mình bằng cách thêm thuộc tính apiErrors vào DS.Model và sau đó trong phân lớp RestAdapter của tôi (tôi đã cần). gọi cho createRecordupdateRecord để lưu lỗi và đặt mô hình ở trạng thái "không hợp lệ", được cho là có nghĩa là xác thực phía máy khách hoặc phía máy chủ không thành công.

Dưới đây là các đoạn mã:

này có thể đi vào application.js hoặc một số khác tập tin cấp cao nhất:

DS.Model.reopen({ 
    // Added for better error handling on create/update 
    apiErrors: null 
}); 

này đi trong callbacks lỗi cho createRecordupdateRecord trong một lớp con RestAdapter:

error: function(xhr, textStatus, err) { 
    console.log(xhr.responseText); 
    errors = null; 
    try { 
     errors = JSON.parse(xhr.responseText).errors; 
    } catch(e){} //ignore parse error 
    if(errors) { 
     record.set('apiErrors',errors); 
    } 
    record.send('becameInvalid'); 
} 
42

Cuối tuần này tôi đang cố gắng tìm ra điều tương tự. Đi theo những gì Luke nói, tôi đã xem xét kỹ hơn nguồn dữ liệu ember cho latest commit (Dec 11).

TLDR; để xử lý lỗi cập nhật/tạo dữ liệu ember, chỉ cần xác định becameError()becameInvalid(errors) trên ví dụ DS.Model của bạn. Dòng thác được kích hoạt bởi lời gọi lỗi AJAX của RESTadapter cuối cùng sẽ gọi các hàm này mà bạn định nghĩa.

Ví dụ:

App.Post = DS.Model.extend 
    title: DS.attr "string" 
    body: DS.attr "string" 

    becameError: -> 
    # handle error case here 
    alert 'there was an error!' 

    becameInvalid: (errors) -> 
    # record was invalid 
    alert "Record was invalid because: #{errors}" 

Dưới đây là toàn bộ đi bộ qua các nguồn:

Trong adapter REST, AJAX hàm lỗi callback được đưa ra here:

this.ajax(this.buildURL(root, id), "PUT", { 
     data: data, 
     context: this, 
     success: function(json) { 
     Ember.run(this, function(){ 
      this.didUpdateRecord(store, type, record, json); 
     }); 
     }, 
     error: function(xhr) { 
     this.didError(store, type, record, xhr); 
     } 
    }); 

didError được định nghĩa here và nó lần lượt gọi recordWasInvalid của cửa hàng hoặc recordWasError tùy thuộc vào phản hồi:

didError: function(store, type, record, xhr) { 
    if (xhr.status === 422) { 
     var data = JSON.parse(xhr.responseText); 
     store.recordWasInvalid(record, data['errors']); 
    } else { 
     store.recordWasError(record); 
    } 
    }, 

Đổi lại, store.recordWasInvalidstore.recordWasError (được định nghĩa here) gọi kỷ lục (một DS.Model) 's xử lý. Trong trường hợp không hợp lệ, nó truyền các thông báo lỗi từ bộ điều hợp làm đối số.

recordWasInvalid: function(record, errors) { 
    record.adapterDidInvalidate(errors); 
    }, 

    recordWasError: function(record) { 
    record.adapterDidError(); 
    }, 

DS.Model.adapterDidInvalidateadapterDidError (được định nghĩa here) chỉ đơn giản send('becameInvalid', errors) hoặc send('becameError') mà cuối cùng dẫn chúng ta đến xử lý here:

didLoad: Ember.K, 
    didUpdate: Ember.K, 
    didCreate: Ember.K, 
    didDelete: Ember.K, 
    becameInvalid: Ember.K, 
    becameError: Ember.K, 

(Ember.K chỉ là một chức năng giả trả lại this Xem here.)

Vì vậy, kết luận là, bạn chỉ cần xác định các hàm cho becameInvalidbecameError trên mô hình của bạn để xử lý các trường hợp này.

Hy vọng điều này sẽ giúp người khác; các tài liệu chắc chắn không phản ánh điều này ngay bây giờ.

+2

Bạn cũng có thể sử dụng gọi lại trong thời gian bằng cách thêm 'model.one ('becameInvalid', function() {// error handling here})' trước khi bạn cam kết giao dịch, nếu bạn muốn xử lý các lỗi khác nhau tùy theo ngữ cảnh. –

+1

Điều này dường như không hoạt động để tiêu diệt. Đúng không? – RyanJM

+0

Giải thích tuyệt vời! Cám ơn rất nhiều. – incognick

3

Tôi chỉ gặp phải tình huống như vậy, không chắc liệu điều này đã được giải thích ở bất kỳ đâu.

Tôi đang sử dụng:

Em.VERSION : 1.0.0 
DS.VERSION : "1.0.0-beta.6" 
Ember Validations (dockyard) : Version: 1.0.0.beta.1 
Ember I18n 

Mô hình này bước đầu đã được mixedin với Validation mixin.

App.Order = DS.Model.extend(Ember.Validations.Mixin, { 
..... 
someAttribute : DS.attr('string'), 
/* Client side input validation with ember-validations */ 
validations : { 
    someAttribute : { 
     presence : { 
      message : Ember.I18n.t('translations.someAttributeInputError') 
     } 
    } 
} 
}); 

Trong mẫu, tay lái tương ứng được thêm vào. (Lưu ý rằng kiểm chứng thực ember sẽ tự động thêm lỗi để model.errors.<attribute> trong trường hợp vụ việc phê chuẩn đầu vào, tôi sẽ sử dụng cùng một trade-off trong kiểm chứng thực máy chủ cũng)

<p>{{t 'translations.myString'}}<br> 
    {{view Ember.TextField valueBinding="attributeName"}} 
    {{#if model.errors.attributeName.length}}<small class="error">{{model.errors.attributeName}}</small>{{/if}} 
</p 

Bây giờ, chúng ta sẽ tiết kiệm Order

App.get('order').save().then(function() { 
    //move to next state? 
}, function(xhr){ 
    var errors = xhr.responseJSON.errors; 
    for(var error in errors){ //this loop is for I18n 
    errors[error] = Ember.I18n.t(errors[error]); 
    } 
    controller.get('model').set('errors', errors); //this will overwrite current errors if any 
}); 

Bây giờ nếu có một số xác nhận lỗi ném từ máy chủ, các gói dữ liệu trở lại đang được sử dụng là

{"errors":{"attributeName1":"translations.attributeNameEror", 
"another":"translations.anotherError"}} 

status : 422 

Điều quan trọng là sử dụng tư cách là

Vì vậy, thuộc tính của bạn (s) có thể được xác thực phía khách hàng và một lần nữa trên phía máy chủ.

Tuyên bố từ chối trách nhiệm: Tôi không chắc đây có phải là cách tốt nhất hay không!

Các vấn đề liên quan