2015-01-21 11 views
7

Tôi đang gặp một chút tình huống lạ, tôi đang xử lý đơn vị tiền tệ trong ứng dụng của mình. Về phía mô hình, tôi tiết kiệm tiền tệ như xu trước khi gửi đến máy chủ như tôi không muốn đối phó với các điểm thập phân ở phía máy chủ. Tuy nhiên, trong chế độ xem, tôi muốn hiển thị đơn vị tiền tệ thông thường chứ không phải là xu.dịch giữa đầu vào cent và đô la trong đầu vào html trong React

Vì vậy, tôi có lĩnh vực đầu vào này, nơi tôi lấy dữ liệu từ đô la và thay đổi nó thành xu:

<input name="balance" type="number" step="0.01" min="0" placeholder="Balance in cents" onChange={this.handleUpdate} value={this.props.user.balance/100)} /> 

Và khi có một sự thay đổi trong giá trị đầu vào, tôi thay đổi nó trở lại xu trước khi gửi nó phía trên:

handleUpdate: function(e) { 

    var value = e.target.value; 

    // changing it back from cents to dollars 
    value = parseFloat(value) * 100; 

    // save back to the parent component managing the prop 
    this.props.onUserUpdate(value); 

} 

Điều này khiến tôi trở nên bế tắc, không có cách nào để tôi nhập dấu thập phân "." Hãy để tôi chứng minh:

  1. 33 vào hộp nhập liệu -> trở thành 3300 trong tình trạng mẹ -> quay ngược lại như 33 trong prop thành phần - tất cả tốt

  2. 33.3 vào hộp nhập liệu -> trở thành 3330 ở trạng thái gốc -> quay trở lại làm 33.3 trong thành phần chống đỡ - tất cả tốt

  3. 33. vào hộp nhập liệu -> trở thành 3300 trong tình trạng mẹ -> quay ngược lại như 33 trong prop thành phần - đây là vấn đề

Như bạn có thể thấy trong trường hợp # 3, khi trước tiên người dùng nhập "." điều này không dịch trở lại cùng một số với "."

Vì đó là đầu vào được kiểm soát, về cơ bản không có cách nào để viết "."

Tôi đã cố gắng sử dụng yếu tố không kiểm soát được với defaultValue, nhưng số lượng prop chưa sẵn sàng thời điểm thành phần được trả lại vì vậy nó chỉ có sản phẩm nào

http://jsfiddle.net/fpbhu1hs/

Trả lời

10

kiểm soát đầu vào sử dụng các giá trị có nguồn gốc có thể tinh quái - nếu bạn cần phải có khả năng hiển thị đầu vào không hợp lệ hoặc ngược lại ...

  1. luôn giữ của value đầu vào trong thành phần của nó của riêng state

    <input value={this.state.value} onChange={this.handleUpdate} // rest as above... 
    
  2. lấy được ban đầu value trong getInitialState()

    getInitialState: function() { 
        return {value: this.props.user.balance/100} 
    } 
    
  3. thực hiện componentWillReceiveProps(nextProps) để phát hiện khi giá trị của prop đang thay đổi từ ở trên và lấy lại chỉ số e giá trị

    componentWillReceiveProps: function(nextProps) { 
        if (this.props.user.balance != nextProps.user.balance) { 
        this.setState({value: nextProps.user.balance/100}) 
        } 
    } 
    

Bây giờ khi người dùng nhập vào "33.", bạn lưu trữ đầu vào văn chương của họ sử dụng setState(), sau đó gọi lại cho phụ huynh.

handleUpdate: function(e) { 
    var value = e.target.value 
    this.setState({value: value}) 
    this.props.onUserUpdate(parseFloat(value) * 100) 
} 

Nếu giá trị phụ huynh thì họ sẽ trả lại xuống cho đứa trẻ qua đạo cụ đã không thay đổi (3300 == 3300 trong trường hợp này), sau đó componentWillReceiveProps() sẽ không làm bất cứ điều gì.

đoạn làm việc:

<script src="http://fb.me/react-with-addons-0.12.2.js"></script> 
 
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script> 
 
<div id="example"></div> 
 
<script type="text/jsx;harmony=true">void function() { 'use strict'; 
 

 
var Parent = React.createClass({ 
 
    getInitialState() { 
 
    return {cents: 3300} 
 
    }, 
 
    
 
    _changeValue() { 
 
    this.setState({cents: Math.round(Math.random() * 2000 + Math.random() * 2000)}) 
 
    }, 
 

 
    _onCentsChange(cents) { 
 
    this.setState({cents}) 
 
    }, 
 

 
    render() { 
 
    return <div> 
 
     <p><strong>Cents:</strong> {this.state.cents.toFixed(0)} <input type="button" onClick={this._changeValue} value="Change"/></p> 
 
     <Child cents={this.state.cents} onCentsChange={this._onCentsChange}/> 
 
    </div> 
 
    } 
 
}) 
 

 
var Child = React.createClass({ 
 
    getInitialState() { 
 
    return {dollars: this.props.cents/100} 
 
    }, 
 

 
    componentWillReceiveProps(nextProps) { 
 
    if (this.props.cents != nextProps.cents) { 
 
     this.setState({dollars: nextProps.cents/100}) 
 
    } 
 
    }, 
 

 
    _onChange(e) { 
 
    var dollars = e.target.value 
 
    this.setState({dollars}) 
 
    if (!isNaN(parseFloat(dollars)) && isFinite(dollars)) { 
 
     this.props.onCentsChange(parseFloat(dollars) * 100) 
 
    } 
 
    }, 
 

 
    render() { 
 
    return <div> 
 
     <input type="number" step="0.01" min="0" value={this.state.dollars} onChange={this._onChange}/> 
 
    </div> 
 
    } 
 
}) 
 

 
React.render(<Parent/>, document.querySelector('#example')) 
 

 
}()</script>

+0

Rất đẹp! Suy nghĩ React yêu cầu một số điều chỉnh ... Cảm ơn bạn! – Michael

+0

Ví dụ của bạn hoạt động với React 0.14.0 https://jsfiddle.net/7h5o97wL/ nhưng không hoạt động React 15.4.2 https://jsfiddle.net/69z2wepo/73775/ –

+0

Đây là vấn đề của tôi https://github.com/facebook/phản hồi/vấn đề/7253 –

0

Tôi đang sử dụng giải pháp đơn giản này để xử lý đầu vào kiểm soát và các giá trị thập phân.

  1. Tạo hai đạo cụ trong trạng thái của bạn, một để giữ giá trị thực tế và một để giữ chuỗi.

    constructor(props) { 
        .... 
    
        this.state = { 
         myProperty: 1.42, 
         myPropertyString: '1.42' 
        } 
    } 
    
  2. Đặt giá trị đầu vào của bạn để String một

    <input type="text" 
         onChange={this.handleUpdate} 
         value={this.state.myPropertyString}/> 
    
  3. Trong handleUpdate phương pháp cập nhật cả hai biến trạng thái.

    handleUpdate(e) { 
        this.setState({ 
         myProperty: parseFloat(e.target.value), 
         myPropertyString: e.target.value 
        }); 
    } 
    
Các vấn đề liên quan