如何在TagHelpers中更改ModelExpression的Classtype?

时间:2017-10-09 22:57:10

标签: c# razor asp.net-core asp.net-core-tag-helpers

我想创建一个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工作。

有什么建议吗?

1 个答案:

答案 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.

我想不出一种方法来简化它,尽管它仍然是强类型的。