我想创建一个Tag Helper,它接受特定模型的某些属性名称。
public class DataTableColumnTagHelper : TagHelper
{
public ModelExpression For { get; set; } //This is for ViewModel
public override void Process(TagHelperContext context, TagHelperOutput output)
{
base.Process(context, output);
}
}
默认情况下,For
以上绑定ViewModel
。是否有可能将它绑定到另一个类?
我首先尝试使用DataTableColumnTagHelper<TModel>
的泛型类型参数来执行此操作,但<data-table-column<SomeModel>>
不是有效的语法。
我目前让它以这种方式工作:
Tag Helper:
public class DataTableColumnTagHelper : TagHelper
{
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "p";
output.Content.SetContent(For.Metadata.PropertyName);
base.Process(context, output);
}
}
查看模型
public class UserGroupViewModel : BaseViewModel
{
public UserGroupTableItem TableItem => null;
}
查看:
<data-table-column for="TableItem.Id"></data-table-column>
<data-table-column for="TableItem.Label"></data-table-column>
<data-table-column for="TableItem.PermissionQuantity"></data-table-column>
我的目标是删除TableItem
属性,因为只有虚拟才能使ModelExpression
工作。
有什么建议吗?
答案 0 :(得分:0)
根据您的示例; class ConfigBlock extends Component {
constructor () {
super()
this.state = {
nextID = 0,
children: [],
}
this.handleChildUnmount = this.handleChildUnmount.bind(this);
// bind this function once here rather than creating new bound functions every render
this.addBlock = this.addBlock.bind(this)
}
handleChildUnmount = (key) => {
console.log(key)
this.setState(state => {
return {
// `state.children.splice(key, 1)`, aside from mutating the state,
// will not work as expected after the first unmount as the ids and
// array positions won't stay aligned
children: state.children.slice().filter(child => child.id !== key)
}
})
}
// Consolidate the two addBlock functions, given we're determining the type
// of component to render in the render function.
addBlock(blockType) {
this.setState(state => {
return {
children: [...state.children, { id: state.nextID, type: blockType }]
nextID: state.nextID + 1
}
})
}
render () {
const {classes} = this.props;
return (
<div className={classes.container}>
<Card className={classes.card}>
<CardContent>
<Typography className={classes.title} color="primary">
Config
</Typography>
<div>
{this.state.children.map(child => {
// determine the component to render here rather than in the handlers
if (child.type === 'server') {
return <ServerBlock key={child.id} id={child.id} unmountMe={this.handleChildUnmount(child.id)} />
} else if (child.type === 'upstream') {
return <UpstreamBlock key={child.id} id={child.id} unmountMe={this.handleChildUnmount(child.id)} />
}
})}
</div>
</CardContent>
<CardActions>
<Button variant="contained" color="primary" className={classes.button} onClick={this.addBlock('server')}>
Server
<AddIcon />
</Button>
<Button variant="contained" color="primary" className={classes.button} onClick={this.addBlock('upstream')}>
Upstream
<AddIcon />
</Button>
</CardActions>
</Card>
</div>
);
}
}
,剃须刀假定您的意思是<data-table-column for="TableItem.Id">
。 Razor将生成类似这样的代码来设置每个Model.TableItem.Id
的{{1}}属性的值;
TagHelper
(Source)
如果为属性值加上ModelExpression
前缀,则生成的代码将删除隐式ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.TableItem.Id);
,以便可以将@
绑定到任何c#表达式;
__model.
我想不出一种方法来简化它,尽管它仍然是强类型的。