Ionic StencilJS:当父对象更改Prop中的属性时如何刷新UI

lqfhib0f  于 2023-05-15  发布在  Ionic
关注(0)|答案(1)|浏览(226)

我们有一个在StencilJS中制作的组件,它有一个Prop(),由使用它的父对象设置,我们希望每次父对象更改这个Prop()时,UI都会更新,因为根据这个prop的值,UI会有所不同。

@Prop()
public field!: Field;

问题是,我们的Prop是一个复杂的对象(Field),我们并没有完全从父对象更改prop,我们只是更改了这个对象内部的属性。
Prop()的类型如下所示,我们正在更改属性required和readOnly。

export interface Field {
    id: string;
    required: boolean;
    readOnly: boolean;
}

我们尝试了不同的方法来实现这一点:
我们创建了状态,并将它们链接到我们想要更新的属性:

@State()
    private readOnly: boolean = this.field.readOnly;

    @State()
    private required: boolean = this.field.required;

我们也尝试了Watch(),但当Prop改变时它没有被调用:

@Watch('field')
    watchFieldChange(newValue: Field) {
        this.readOnly = newValue.readOnly;
        this.required = newValue.required;
    }

最后,我们尝试在Prop()上使用mutable和reflect,并在父对象上重新分配整个值:

@Prop({mutable: true, reflect: true})
    public field!: Field;
    component.field.required = !component.field.required;
    component.field.readOnly = !component.field.readOnly;
        
    component.field = { ...component.field};

这个最后的解决方法在我们的项目上下文中起作用,但是我们的模具项目作为一个库工作,所以当我们试图在另一个项目中导入这个库并使用解决方法时,它不起作用。
我们不知道如何解决这个问题,而不必为我们希望在视图中更新的每个变量使用单独的Prop。如果任何人有任何想法或面临这一点之前,并知道一个变通办法,使这项工作,请让我们知道!
我在离子论坛上发布了同样的问题,但没有人回答(所以如果你愿意,你可以在那里回答,如你所愿):https://forum.ionicframework.com/t/how-to-refresh-ui-when-parent-changes-a-property-inside-a-prop/232993/1
非常感谢!

daupos2t

daupos2t1#

spread运算符应该可以工作-这在文档中有介绍:https://stenciljs.com/docs/reactive-data#updating-an-object。

export class Parent {
    childElement;
    field = { readonly: false };

    setReadonly() {
        this.field.readonly = true;
        this.childElement.field = { ...this.field };
    }

    render() {
        <child ref={el => this.childElement = el} field={this.field}>
        </child>
    }
}

另一种选择是更“蛮力”的技术。添加一个@Method用于设置值,您可以通过内部@State属性实现自己的更改检测和触发重新呈现策略:

@State() update: number = 0;
@Prop() field: Field;
@Method() setField(newField: Field) {
    if (newField?.readonly !== this.newField?.readonly) {
        this.field = newField;
        this.update++;
    }
}

但是我必须重申-如果正确使用,spread操作符应该工作-无论组件是否在单独的库中。如果它不起作用,也许你做得不好。尝试创建一个简单的测试用例来验证。

相关问题