2011-05-11 42 views
24

Tôi đang di chuyển ứng dụng của mình từ phiên bản ExtJs 3 đến 4. Tôi có một số combobox ở formPanel của tôi, và trước đây tôi đã sử dụng hiddenName và tất cả những gì stuff để gửi valueField thay vì displayField.Giá trị mặc định của combobox Extjs 4

Tất cả sự thích ứng của tôi hoạt động tốt (trường giá trị được gửi), nhưng tôi không thể đặt giá trị mặc định cho combobox, chúng được hiển thị dưới dạng trống sau khi tải trang. Trước đây, tôi đã làm điều đó chỉ với việc xác định tham số 'value' trong config. Có ý tưởng nào để khắc phục điều đó không?

Mã của tôi - Model và Store:

Ext.define('idNamePair', { 
    extend: 'Ext.data.Model', 
    fields: [ 
     {name: 'id', type: 'string'}, 
     {name: 'name', type: 'string'} 
    ] 
}); 

var dirValuesStore = new Ext.data.Store({ 
    model: 'idNamePair', 
    proxy: { 
     type: 'ajax', 
     url: '../filtervalues.json', 
     reader: { 
      type: 'json', 
      root: 'dir' 
     } 
    }, 
    autoLoad: true 
}); 

Combo config:

{ 
    triggerAction: 'all', 
    id: 'dir_id', 
    fieldLabel: 'Direction', 
    queryMode: 'local', 
    editable: false, 
    xtype: 'combo', 
    store : dirValuesStore, 
    displayField:'name', 
    valueField:'id', 
    value: 'all', 
    width: 250, 
    forceSelection:true 
} 
+0

Xin vui lòng gửi một số mẫu mã để chúng ta hãy nhìn vào vấn đề và giải pháp khả thi. –

+0

Câu hỏi là chính xác. Không có mã yêu cầu ngay cả khi tôi không biết câu trả lời nguyên nhân tôi vẫn bị mắc kẹt trong 3.x – sra

+0

Tôi đoán nó lại là một câu hỏi tải không đồng bộ của cửa hàng và combo, bởi vì nếu cửa hàng được xác định bên trong combo - nó hoạt động tốt . – BlackLine

Trả lời

4

tôi nhận thấy cấu hình Combo của bạn có queryMode: 'local'. Giá trị đó dành cho thời điểm dữ liệu của bạn được lưu trữ cục bộ trong một mảng. Nhưng mô hình của bạn đang sử dụng proxy AJAX. Nó có thể được rằng điều này confuses Ext vì vậy nó không thể tìm thấy giá trị mặc định bạn đang cố gắng để thiết lập? Hãy thử xóa queryMode để giá trị mặc định thành giá trị 'từ xa' (hoặc đặt rõ ràng.)

CẬP NHẬT: Tôi đã di chuyển ứng dụng của riêng mình từ Ext3 đến 4 ngay sau khi đăng bài ở trên và tôi gặp phải vấn đề tương tự . Tôi chắc chắn queryMode là một phần của nó, nhưng vấn đề chính là combobox không có dữ liệu cần thiết nhưng tại thời điểm nó được trả lại. Đặt value không cung cấp cho nó giá trị nhưng không có gì trong kho dữ liệu chưa khớp với, vì vậy trường sẽ trống. Tôi phát hiện ra rằng thuộc tính autoLoad cũng có thể chỉ định chức năng gọi lại được sử dụng khi dữ liệu được tải. Dưới đây là những gì bạn có thể làm:

store: new Ext.data.Store({ 
    model: 'MyModel', 
    autoLoad: { 
     scope: this, 
     callback: function() { 
      var comboBox = Ext.getCmp("MyComboBoxId"); 
      var store = comboBox.store; 

      // set the value of the comboBox here 
      comboBox.setValue(blahBlahBlah); 
     } 
    } 
    ... 
}) 
17

Tôi gặp phải vấn đề tương tự, afaik phải làm với việc chọn danh sách lựa chọn trước khi các mục được thêm vào cửa hàng. Tôi đã thử phương pháp gọi lại được đề cập ở trên mà không có bất kỳ may mắn nào (đoán nó sẽ phải là một cuộc gọi lại trên danh sách lựa chọn thay vì cửa hàng).

tôi đã thêm dòng này sau khi thêm mục vào cửa hàng và nó hoạt động tốt:

Ext.getCmp('selectList').setValue(store.getAt('0').get('id')); 
+0

Cảm ơn, bạn hoàn toàn đúng –

0

Tôi đặt cược này đã làm với thời gian bạn (không đồng bộ) nạp combobox, và thời gian bạn thiết lập giá trị của combobox. Để khắc phục sự cố này, chỉ cần thực hiện việc này:

Ext.define('idNamePair', { 
    extend: 'Ext.data.Model', 
    fields: [ 
     {name: 'id', type: 'string'}, 
     {name: 'name', type: 'string'} 
    ] 
}); 

var dirValuesStore = new Ext.data.Store({ 
    model: 'idNamePair', 
    proxy: { 
     type: 'ajax', 
     url: '../filtervalues.json', 
     reader: { 
      type: 'json', 
      root: 'dir' 
     } 
    }, 
    autoLoad: false // set autoloading to false 
}); 

Tự động tải của cửa hàng bị tắt. Bây giờ, sau bạn đã đặt ComboBox của mình ở một nơi nhất định - sử dụng mã trong bài đăng bắt đầu của bạn - bạn chỉ cần tải cửa hàng theo cách thủ công: dirValuesStore.load();.

Đó có thể là sau cấu hình Ext.apply(this, {items: [..., {xtype: 'combo', ...}, ...]}) trong một số thành phần của initComponent().

0

Hãy thử mã này:

var combo = new Ext.form.field.ComboBox({ 
    initialValue : something, 
    listeners: { 
     afterrender: function(t,o) { 
      t.value = t.initialValue;  
     } 
    } 
}) 
3

Bạn có thể đặt logic trực tiếp vào gọi lại, hoặc thiết lập một chức năng để xử lý tất cả các cửa hàng.

var store1 = Ext.create('Ext.data.Store', { 
    ... 
    autoLoad: { 
     callback: initData 
    } 
}); 

var store2 = Ext.create('Ext.data.Store', { 
    ... 
    autoLoad: { 
     callback: initData 
    } 
}); 

var myComboStores = ['store1', 'store2'] 

function initData() { 
    var loaded = true; 
    Ext.each(myComboStores, function(storeId) { 
     var store = Ext.StoreManager.lookup(storeId); 
     if (store.isLoading()) { 
      loaded = false; 
     } 
    } 
    if(loaded) { 
     // do stuff with the data 
    } 
} 

=====================

Đối với những người đọc, giá trị config/tài sản trên 'kết hợp' của bạn đối tượng nên được đặt thành một số giá trị để hộp kết hợp nhận giá trị ban đầu. Bạn đã làm điều này rồi. Giá trị 'tất cả' cũng cần phải ở trong cửa hàng của bạn trước khi nó sẽ đặt giá trị làm mặc định.

value: 'all' 

Ngoài ra, đó là thực hành tốt để thiết lập một giá trị cho valueField cấu hình, mà bạn đã làm rồi. Nếu không, trình lắng nghe chọn sẽ không nhận được giá trị chính xác khi gọi hàm combo.getValue().

4

Cách tốt nhất để thực hiện việc này là nghe sự kiện afterrender và sau đó đặt giá trị mặc định trong hàm gọi lại.

Xem mã này:

new Ext.form.field.ComboBox({ 
    //This is our default value in the combobox config 
    defaultValue: 0, 
    listeners: { 
     //This event will fire when combobox rendered completely 
     afterrender: function() { 
      //So now we are going to set the combobox value here. 
      //I just simply used my default value in the combobox definition but it's possible to query from combobox store also. 
      //For example: store.getAt('0').get('id'); according to Brik's answer. 
      this.setValue(this.defaultValue);  
     } 
    } 
}); 
10

Thêm loading: true để cấu hình cửa hàng của bạn sẽ sửa chữa nó. Có vẻ như có vấn đề với autoLoad: trueforceSelection: true. Hack nhỏ này sẽ làm cho combobox của bạn tin rằng cửa hàng đang tải ngay cả khi chức năng tải chưa được kích hoạt.

+0

@BlackLine Nice! Tôi sẽ bỏ phiếu hai lần! Giải pháp này rất đơn giản và hiệu quả. – leaf

+1

Đối với những người tò mò về lý do tại sao công trình này hoạt động, đó là do [Nhà xây dựng cửa hàng] (http://docs.sencha.com/extjs/4.2.1/source/Store.html#Ext-data-Store-method- constructor), ngăn chặn cuộc gọi tải 'autoLoad' bằng 1ms (xem ở cuối mã của hàm tạo). Do đó, thuộc tính 'loading' của cửa hàng được đặt thành' true' chỉ sau khi phương thức 'setValue' của hộp kết hợp được gọi, và vì vậy cửa hàng kết hợp cho rằng cửa hàng được nạp và giá trị không hợp lệ (vì cửa hàng nằm trong thực tế trống). – rixo

+1

Tôi khuyên bạn nên sửa chữa toàn bộ hệ thống bằng cách ghi đè 'Ext.data.Store # constructor' để đặt' loading' thành 'true' nếu' autoLoad' cũng là 'true'. Ví dụ. 'Mở rộng.xác định (null, { \t override: 'Ext.data.Store', \t constructor: function() { \t \t this.callParent (arguments); \t \t if (this.autoLoad) { \t \t \t this.loading = true; \t \t} \t} }); ' – rixo

0

Chỉ định tham số 'giá trị' trong cấu hình là cách chính xác để đặt giá trị mặc định cho combobox.

Trong ví dụ của bạn, chỉ cần đặt forceSelection:false, nó sẽ hoạt động tốt.

Trong trường hợp bạn muốn đặt forceSelection:true, bạn phải đảm bảo dữ liệu được trả về từ cửa hàng của bạn chứa một mục có giá trị bằng với giá trị mặc định của bạn ('tất cả' trong trường hợp này). văn bản trống theo mặc định. Để được rõ ràng hơn, hãy thay thế định nghĩa dirValuesStore của bạn bằng cách này:

var dirValuesStore = Ext.create('Ext.data.Store', { 
     fields: ['id', 'name'], 
     data: [ 
      {id: 'all', name: 'All'}, 
      {id: '1', name: 'Name 1'}, 
      {id: '2', name: 'Name 2'}, 
      {id: '3', name: 'Name 3'}, 
      {id: '4', name: 'Name 4'} 
     ] 
    }) 

Bạn sẽ thấy nó hoạt động!

0

Trong ExtJS 5.0.1 này nên làm việc, trong cấu hình kết hợp:

... 
editable: false, 
forceSelection: true, 
emptyText: '', 
Các vấn đề liên quan