我认为给定controller
& view
属性,当控制器的状态发生变化(或m.prop
属性发生变化)时,它会重新呈现模板。在我的情况下,这不会发生(我必须直接使用redraw
)。我在这做错了什么?
//////// app.js
define([ 'mithril', 'propertyPane'],
function(m, propertyPane){
//div#properties exists
m.module(document.getElementById('properties'),propertyPane);
});
///////propertyPane.js
define([ 'mithril', 'emitter'],
function(m, emitter) {
//mithril "namespace"
var propertyPane = {};
///////////////////////
// Models //
///////////////////////
propertyPane.PropertyList = Array;
propertyPane.Property = function(name, data) {
//the following reflects the format of the data obects as sent by the event emitter
this.name = m.prop(name);
this.value = m.prop(data.value);
this.type = m.prop(data.valueType);
this.visible = m.prop(data.userVisible);
this.editable = m.prop(data.userEditable);
};
///////////////////////
// Controller //
///////////////////////
propertyPane.controller = function() {
this.properties = propertyPane.PropertyList();
this.updatePropertyPane = function(sender) {
//destroy current list
this.properties.length = 0;
for( var key in sender.currentItem.tag){
this.properties.push(new propertyPane.Property(key, sender.currentItem.tag[key]));
}
//>>>This is required to make the property pane to rerender:<<<
// m.redraw(); //why?
//why doesn't redraw happen automatically (because I'm using m.module)??
}.bind(this);
//this reliably updates the the properties list
//but rerender does not happen
emitter.addCurrentItemChangedListener(this.updatePropertyPane);
};
///////////////////////
// View //
///////////////////////
propertyPane.view = function(ctrl){
return m('ul',
ctrl.properties.map(function(property){
return m('li', property.name() + ' ' + property.value());
})
);
};
return propertyPane;
});
我还尝试添加一个名为foo
的属性,该属性在updatePropertyPane
中更新了:
//in controller
this.foo = m.prop(Date.now());
//in updatePropertyPane
this.foo(Date.now());
//in view
m('li', ...+this.foo()) //to make sure the view accesses this property.
那也不起作用。
答案 0 :(得分:3)
令人惊讶的是,m.prop
非常多地返回一个getter / setter而没有副作用。
Mithril hooks本身就是你观点的事件听众。
因此,在我使用秘银的经验非常有限的情况下,您应该使用m
来设置您的事件监听器,或者使用m.startComputation / m.endComputation
来调用m.redraw
,并允许您使用{{1}}的不同部分。应用到only redraw once尽管更新了几件事。
答案 1 :(得分:2)
秘银自动重新渲染
数据绑定值更改本身不会导致重新呈现,这有几个原因。公平地说,Mithril中的大多数数据更改都发生在事件处理程序中或AJAX处理期间。
但是,您可以使用m.prop()的修改版本强制重新更改值:
mprop: function(store, onchange) {
var prop = function() {
if (arguments.length) {
store = arguments[0];
if (typeof onchange == 'function') { onchange(store); }
}
return store;
}
prop.toJSON = function() { return store; }
return prop;
}
this.name = mprop("John", function(value) {
// value is the new value
// do a m.redraw() rather than m.startComputation / m.endComputation
});
但是你这样做,你应该更喜欢m.redraw()用于m.startComputation / m.endComputation上的异步事件。它重绘了当前活动模块的视图,并由Mithril的自动重绘系统在内部调用。