2015-07-28 1 views
2

Похоже, что у меня есть недоразумение со временем привязки. У меня есть простой combobox со значением, привязанным к некоторому объекту в viewmodel. Выбор нового значения, событие смены огня, которое запускается после метода setValue, поэтому мое новое значение уже установлено, но моя модель просмотра еще не обновлена. Когда моя модель просмотра будет обновлена? Я нашел некоторую информацию о планировщике, в которой говорится, что мне нужно запустить метод notify(), чтобы немедленно применить изменения к viewmodel, но мне это совсем не помогает.ExtJS 5.1.1 Немедленное связывание с огнем в ViewModel

Ext.define('MyModel', { 
    extend: 'Ext.data.Model', 
    idProperty: 'foo', 
    fields: [{ 
     name: 'bar', 
     type: 'string' 
    }] 
}); 

Ext.define('MyViewModel',{ 
    extend: 'Ext.app.ViewModel', 
    alias: 'viewmodel.my', 
    data: { 
     testObj: { 
      foo: null, 
      bar: null 
     } 
    }, 
    stores:{ 
     combostore: { 
      model: 'MyModel', 
      data: [{ 
       foo: '1', 
       bar: 'qwerty' 
      },{ 
       foo: '2', 
       bar: 'ytrewq' 
      }] 
     } 
    } 
}); 

Ext.define('MyViewController', { 
    extend: 'Ext.app.ViewController', 
    alias: 'controller.my', 
    onChange: function() { 
     var vm = this.getViewModel(); 
     vm.notify(); 
     console.log(vm.get('testObj.foo'));//supposed to be current value 
    } 
}); 

Ext.application({ 
    name : 'Fiddle', 

    launch : function() { 
     Ext.create('Ext.container.Viewport', { 
      controller: 'my', 
      viewModel: { 
       type: 'my' 
      }, 
      layout : 'vbox', 
      items : [ 
       { 
        xtype : 'combo', 
        valueField: 'foo', 
        displayField: 'bar', 
        queryMode: 'local', 
        bind: { 
         store: '{combostore}', 
         value: '{testObj.foo}' 
        }, 
        listeners:{ 
         change: 'onChange' 
        } 

       } 
      ] 
     }); 
    } 
}); 

Вот скрипку как хорошо: https://fiddle.sencha.com/#fiddle/r88

+0

Я верю, что 'vm.notify()' не будет выполнять свою работу синхронно. Обратите внимание, что добавление опции 'delay: 1' в конфигурацию слушателей делает трюк, даже' vm.notify() 'становится излишним. – Greendrake

+0

Если вам нужно использовать 'delay: 1', он должен вызывать все звонки, которые вы делаете неправильно. То же самое для вызова 'notify()' таким образом. – Tarabass

+0

1. По умолчанию в хранилище есть своя конфигурация 'autoSync' для false. Возможно, вам нужно установить его в true для comboStore в вашем представленииModel? | 2. Не следует проверять хранилище в событии onChange вашего комбо, потому что комбо не успевает синхронизировать ваш магазин ... | Замечание: в extjs вы не изменяете значение combo, а содержимое магазина, поэтому, если вы хотите проверить любые изменения в своем комбо, проверьте его в своем магазине – Michel

ответ

0

не следует вызывать оповещать непосредственно на ViewModel. Частный: http://docs.sencha.com/extjs/5.0/5.0.1-apidocs/#!/api/Ext.app.ViewModel-method-notify

Просто установите данные, вызвав vm.setData ({}).

onChange: function(cb, newValue, oldValue) { 
    var vm = this.getViewModel(); 

    console.log('newValue', newValue); 
    console.log('oldValue', oldValue); 
    this.getViewModel().setData({'testObj': {'foo': newValue}}); 
    console.log(vm.get('testObj.foo'));//supposed to be current value 
} 

Тем не менее вы можете рассмотреть следующий пример, в котором я использую формулу для получения выбранной модели combobox. Посмотрите, что я удалил слушателя, добавил ссылку на выпадающее имя и создал формулу, чтобы привязать ее к выбранной записи.

Ext.define('MyModel', { 
    extend: 'Ext.data.Model', 
    idProperty: 'foo', 
    fields: [{ 
     name: 'bar', 
     type: 'string' 
    }] 
}); 

Ext.define('MyViewModel',{ 
    extend: 'Ext.app.ViewModel', 
    alias: 'viewmodel.my', 
    data: { 
     testObj: { 
      foo: null, 
      bar: null 
     } 
    }, 
    stores:{ 
     combostore: { 
      model: 'MyModel', 
      data: [{ 
       foo: '1', 
       bar: 'qwerty' 
      },{ 
       foo: '2', 
       bar: 'ytrewq' 
      }] 
     } 
    }, 

    formulas: { 
     currentRecord: { 
      bind: { 
       bindTo: '{myCombo.selection}', 
       deep: true 
      }, 
      get: function(record) { 
       return record; 
      }, 
      set: function(record) { 
       this.set('currentRecord', record); 
      } 
     } 
    } 
}); 

Ext.define('MyViewController', { 
    extend: 'Ext.app.ViewController', 
    alias: 'controller.my', 
    onChange: function(cb, newValue, oldValue) { 
     var vm = this.getViewModel(); 

     console.log('newValue', newValue); 
     console.log('oldValue', oldValue); 
     this.getViewModel().setData({'testObj': {'foo': newValue}}); 
     console.log(vm.get('testObj.foo'));//supposed to be current value 
    } 
}); 




Ext.application({ 
    name : 'Fiddle', 

    launch : function() { 
     var vp = Ext.create('Ext.container.Viewport', { 
      controller: 'my', 
      viewModel: { 
       type: 'my' 
      }, 
      layout : 'vbox', 
      items : [ 
       { 
        xtype : 'combo', 
        reference: 'myCombo', 
        valueField: 'foo', 
        displayField: 'bar', 
        queryMode: 'local', 
        bind: { 
         store: '{combostore}', 
         value: '{testObj.foo}' 
        }/*, 
        listeners:{ 
         change: 'onChange' 
        }*/ 
       }, 
       { 
        xtype: 'label', 
        bind: { 
         text: '{currentRecord.foo}' 
        } 
       } 
      ] 
     }); 

     /* Just an example. You could also select records on the combo itself */ 
     vp.getViewModel().setData({'testObj': {'foo': '2'}}); 
    } 
}); 
+0

Спасибо за ответ, но я не хочу использовать ' setData() 'вручную или создать формулы для исправления этого простого связывания. Просто хочу знать, когда моя viewmodel готова после вызова 'setValue()' и почему добавление 'delay: 1' или' buffer: 1' в конфигурацию listener будет делать трюк с доступом к значению в событии изменения combobox, например, @DrakeES , Я полагаю, что я должен смотреть на 'Ext.util.Scheduler' в моей модели viewmodel, потому что я нашел интересную конфигурацию, такую ​​как' tickDelay: 5', которая по умолчанию установлена ​​в 5 миллисекунд. И затем эта конфигурация используется для создания функции отсрочки для таймера, которая будет выполнять следующее уведомление. – Exclaim

+0

TickDelay действительно используется для этого. К сожалению, я не нашел установку TickDelay более высокой ценности очень полезной, потому что она настроена на всю модель. Я также верю, что это личное, поэтому вы не можете полагаться на его существование. – Tarabass

0

Defer будет вашим спасителем:

onChange: function() { 
    var vm = this.getViewModel(); 

    Ext.defer(function(){ 
     console.log(vm.get('testObj.foo'));//supposed to be current value 
    },10,this); 
} 
0

Пожалуйста, используйте select событие вместо change.

Я думаю, что изменение событий срабатывает даже до того, как значение установлено.

 Смежные вопросы

  • Нет связанных вопросов^_^