2017-06-02 216 views
4

我有兩個組件:一個面板和一個自定義文本字段。
該面板有一個視圖模型,我想將該視圖模型的值(稱爲testData)綁定到自定義文本字段的屬性(稱爲test)。
這工作正常......基本上。
但是,當文本字段的test屬性發生更改時,面板視圖模型中的testData不會相應更新。我的意思是,當子元素(文本字段)的test屬性被修改時,面板視圖模型的testData屬性應該包含與test中相同的值,就像普通的雙向綁定一樣。ExtJs父子組件之間的雙向綁定

我不知道我在做什麼錯,但這裏是我試過至今: 所有的https://fiddle.sencha.com/#fiddle/20pu&view/editor

Ext.define('MyMain', { 
    extend: 'Ext.panel.Panel', 
    alias: 'widget.main', 

    width: '100%', 
    bodyPadding: 10, 

    viewModel: { 
     data: { 
      testData: 'Example Data' 
     } 
    }, 

    bind: { 
     title: '{testData}' 
    }, 

    items: { 
     xtype: 'myField', 
     bind: { 
      test: '{testData}' 
     } 
    } 
}) 

Ext.define('MyField', { 
    extend: 'Ext.form.field.Text', 
    alias: 'widget.myField', 
    fieldLabel: 'Data', 
    width: '100%', 

    config: { 
     test: null // when test is changed, it should also affect the {testData} bind of the main component, causing the title to change 
    }, 

    setTest(value) { 
     this.test = value + ' modified!' // because of the bind, this /should/ automatically get appied to the viewmodel's `testData` and thus to the panel title 
     this.setValue(this.test) // whenever the `test` property is changed, we write the contents to the value of the text field (just to visualize the `test` property). 
     // But as you can see, the panel title will still just say `Example Data` and not `Example Data modified!` as it should. 
    }, 
    getTest(){ 
     return this.test 
    } 
}) 

Ext.application({ 
    name : 'Fiddle', 

    launch : function() { 
     Ext.create('Ext.container.Viewport', { 
      items: [{ 
       xtype: 'main' 
      }] 
     }) 
    } 
}) 
+0

首先將'config'作爲默認值,然後使用'test'參數創建組件,該參數將覆蓋'test'中的默認值。 – Edwin

+1

配置值只能從父組件設置一次並不重要。我的主要問題是更改測試值不會影響父組件的viewmodel屬性。任何想法如何可以解決? – Forivin

+1

你沒有任何'測試'在父... ..只是一個'testData' – Edwin

回答

1

更新

一般來說,提的是在config塊財產,包括在publishes將使任何財產雙向綁定(閱讀其他答案你的意見後)。

ExtJS將爲其生成getter和setter方法。 setter方法負責綁定。現在,每當有人更新屬性值(使用setter)時,新值將被傳遞給綁定的viewModel,然後傳遞給其他組件。

直接訪問屬性,this.testthis.viewModel.data.testData並將值分配給它們不會反映在綁定到此屬性的控件中。

如果您正在爲發佈的屬性的setter函數(setTest)提供實現,請確保this.callParent(...)從它被調用。

使用領域的value屬性來顯示test的內容引起了較早的混淆。這是一個fiddle,在MyField類中沒有任何特殊處理,可以使用雙向綁定test屬性。

點擊'Get test'按鈕,該值應該是'Example Data'(來自viewModel)。

'Set testData'按鈕將更新viewModel中的值。再次使用「獲取測試」按鈕來驗證test的值也已更新。

'設置測試'按鈕爲該字段的test屬性分配一個新值,這將反映在面板的標題中。


看看這個forked fiddle

在您的實施中,setTest方法將this.test的值直接更改爲value + ' modified!'。這不會更新viewModel中testData的值,因爲綁定通過配置中指定的屬性實現的getter和setter函數工作。

0

首先,你需要做的test配置twoWayBindable

此對象包含配置屬性的映射,它們將在修改後更新它們的 綁定。

其次,你不需要爲config對象定義getter和setter,就你而言。

每個配置項將有自己的setter和getter方法 在上課 創建時的類原型裏面自動生成的,如果類沒有明確定義 這些方法。

您可能會這樣做,但會重寫負責更新綁定的默認方法等等。

通過標準化這個共同的模式,默認生成的制定者 提供,你可以把自己的自定義 邏輯成,即兩個額外的模板方法:一個「applyFoo」和「updateFoo」方法一「富」 配置項目,它們分別在值實際上設置爲 之前和之後執行。

twoWayBindable配置依賴於更新模板的方法,當你指定自己的二傳手,更新方法永遠不會被調用,並且綁定將不會被更新。

換句話說,當利用配置功能時,你大多從來沒有 需要明確定義setter和getter方法。相反,「應用」 和「更新」方法應在必要時實施。

所以,在你的例子,這裏有你需要採取的步驟:

  1. 取出setTestgetTest方法聲明。
  2. 添加twoWayBindable config,其中包含test

    twoWayBindable: ['test']` 
    
  3. 鉤任何額外的邏輯到applyTestupdateTest模板的方法。例如,在設置測試值後更新字段值。

    updateTest(testValue) { 
        this.setValue(testValue) 
    } 
    

這裏是工作提琴:https://fiddle.sencha.com/#fiddle/20rs&view/editor

+0

似乎無法解決問題。當文本字段被改變時,面板的標題應該與文本字段具有相同的值。每次改變時,面板的標題都應該簡單地與文本字段的測試屬性同步。 – Forivin

+0

當文本字段被改變時,它的'value'改變,而不是'test'配置。我認爲你的'test'配置在別的地方改變了。你爲什麼還需要'test'配置?爲什麼不把'testData'綁定到'value'?這裏:https://fiddle.sencha.com/#fiddle/20se&view/editor – scebotari66

+0

測試屬性是整個點。我很清楚,價值的兩種方式綁定工作。我老實說,甚至不關心價值屬性本身,我只是利用它來可視化測試屬性的內容。 – Forivin

1

如果要更改標題,而改變Textfield,那麼你必須value屬性綁定,因爲改變文本框的值只改變字段的值屬性。

bind: { 
      test: '{testData}', 
      value : '{testData}' 
     }, 

如果你不想用值綁定它,然後在change事件你必須設置test屬性的值。

listeners : { 
       change : function(field, newValue, oldValue, eOpts){ 
        field.setTest(newValue); 
       } 
      } 

請參考fiddle

0
  1. 爲了能夠綁定自定義類屬性,您需要在twoWayBindable配置中列出這些屬性。
  2. 不要修改要在setter中設置的值,也不要遞歸調用setter。最好寫一個update<Fieldname>()函數。這些意味着在你的視圖中處理更新,他們通常不會修改你的數據結構。
  3. 基於2.):重寫表單字段的視圖更新函數以捕獲對該值所做的更改。

下面是完整的小提琴: https://fiddle.sencha.com/#fiddle/218m&view/editor

有些東西這裏要注意:

  • 3秒後,視圖模型TESTDATA值更新
  • 後6秒,setTest( )在9秒後,該字段的setter被稱爲
  • ,觸發輸入字段中的setValue()方法
  • 最後,您可以更改輸入字段值以更改面板標題

這是爲了說明各種情況。