2017-06-02 36 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()方法
  • 最后,您可以更改输入字段值以更改面板标题

这是为了说明各种情况。